{"openapi":"3.0.1","info":{"title":"CurrencyGuard Trading System API (External)","description":"API for the CurrencyGuard trading system, providing comprehensive foreign currency management and trading capabilities.\n\n**Note:** This documentation shows only Regulated & Public endpoints.\n\n### Errors\n\nEvery error is an RFC 9457 problem detail, sent as `application/problem+json`. Branch on the `type` member, never on `detail` — `detail` is prose and may be reworded.\n\nThese can be returned by any endpoint, in addition to the problems listed on individual responses:\n\n| Type | Status | Meaning |\n|---|---|---|\n| [`http/malformed-request`](/problems/http/malformed-request/) | 400 | Request contains malformed data that cannot be parsed |\n| [`security/authentication-failed`](/problems/security/authentication-failed/) | 401 | Authentication credentials are missing, invalid, or expired |\n| [`security/insufficient-permissions`](/problems/security/insufficient-permissions/) | 403 | Authenticated user lacks permission to perform the requested operation |\n| [`http/resource-not-found`](/problems/http/resource-not-found/) | 404 | Requested resource does not exist or has been deleted |\n| [`http/method-not-allowed`](/problems/http/method-not-allowed/) | 405 | The HTTP method is not supported for this resource |\n| [`http/idempotency-key-in-flight`](/problems/http/idempotency-key-in-flight/) | 409 | A request with this idempotency key is already being processed |\n| [`http/idempotency-key-reused`](/problems/http/idempotency-key-reused/) | 409 | An idempotency key was reused with a different request body |\n| [`http/resource-conflict`](/problems/http/resource-conflict/) | 409 | Request conflicts with the current state of the resource |\n| [`http/payload-too-large`](/problems/http/payload-too-large/) | 413 | The request body exceeds the maximum size the endpoint accepts |\n| [`http/unsupported-media-type`](/problems/http/unsupported-media-type/) | 415 | The request body is in a format the endpoint does not accept |\n| [`validation/validation-error`](/problems/validation/validation-error/) | 422 | Generic validation error for request data that doesn't meet business rules |\n| [`security/rate-limit-exceeded`](/problems/security/rate-limit-exceeded/) | 429 | Request rate limit has been exceeded |\n| [`server/database-error`](/problems/server/database-error/) | 500 | Database operation failed or data corruption detected |\n| [`server/internal-error`](/problems/server/internal-error/) | 500 | Unexpected internal server error |\n\nThe full catalogue, including the problems specific to each operation, is at [/problems/](/problems/).\n","termsOfService":"http://currencyguard.com/terms/","contact":{"name":"CurrencyGuard Support","url":"http://currencyguard.com/support","email":"support@currencyguard.com"},"license":{"name":"Proprietary","url":"http://currencyguard.com/license"},"version":"1.0"},"servers":[{"url":"https://api.currencyguard.com","description":"Production"},{"url":"https://sandbox-api.currencyguard.com","description":"Sandbox"}],"security":[{"bearerScheme":[]}],"tags":[{"name":"ApiClient","description":"Machine-to-machine credentials for server-to-server integration. Each API client is an OAuth2 Client Credentials identity scoped to your regulated entity — exchange its client ID and secret for the bearer token that every other endpoint requires. The secret is returned only when a client is created or its secret rotated, and cannot be retrieved afterwards."},{"name":"AuthPoolConfig","description":"Sign-in discovery. Returns the authentication configuration for an email domain, so a login page knows where to send someone before they have a session."},{"name":"Calendar","description":"Business-day calendars. Which days count as working days for a market, and therefore when a trade can settle."},{"name":"CalendarDate","description":"Individual dates within a business-day calendar, including holidays and other non-working days."},{"name":"Company","description":"Companies — the end customers who buy Guards, held under an Introducing Broker. Which operations are available depends on your role."},{"name":"CompanyOffboarding","description":"Winding down a Company — disable it, re-enable it, or permanently erase its personal data."},{"name":"Configuration","description":"Named settings that govern trading behaviour, readable so a client can reflect the same limits and defaults the server enforces."},{"name":"ConfirmationTemplate","description":"Templates for the confirmation documents issued against a Guard, so the paperwork carries your own wording and branding."},{"name":"Currency","description":"Supported currencies and their attributes, including the number of decimal places amounts are held to."},{"name":"CurrencyPair","description":"Tradeable currency pairs and their quoting conventions — which side is the base currency, and how a rate is expressed."},{"name":"CurrencyguardCompany","description":"CurrencyGuard's own legal entities — the counterparty on the other side of the Guards you sell."},{"name":"CustomerManagement","description":"Customers — the individual people who use CurrencyGuard on behalf of a Company. Which operations are available depends on your role."},{"name":"Documents","description":"Stored documents and their content, addressed by id and limited to those in your own scope."},{"name":"EntitlementsTemplate","description":"Entitlements templates — named sets of fine-grained permissions applied to users, so access is granted by role rather than one flag at a time."},{"name":"Guard","description":"Guards — the core product. A Guard protects a Company against an adverse exchange rate move: they fix a rate now for currency they will need later, and settle against it during an agreed window. These endpoints cover a Guard once it exists — viewing it, quoting an extension, calculating a cancellation refund, and cancelling."},{"name":"GuardConfirmation","description":"The confirmation document for a Guard — a PDF record of its terms, for the customer's own files."},{"name":"GuardPricing","description":"Indicative Guard pricing, without authentication. Quote a Guard or an extension, list supported pairs, and read product information — for calculators and other public-facing tools. Indicative only: a firm, buyable price comes from a Guard quote."},{"name":"GuardQuote","description":"Guard quotes — a firm, time-limited price. Create a quote, then buy from it before it expires. Extensions are quoted and bought the same way."},{"name":"GuardSettlement","description":"Settling a Guard — exchanging currency at the protected rate during its settlement window, in one go or in parts."},{"name":"HistoricPerformance","description":"Historic FX performance analysis — how a currency pair has moved over a period, including its best and worst outcomes, for showing what protection would have been worth."},{"name":"IntroducingBroker","description":"Introducing Brokers — the intermediaries that introduce Companies to a Regulated Entity and hold the relationship with them."},{"name":"Invitation","description":"Invitations — how a new user is brought onto the platform. Create one, track it, resend or revoke it."},{"name":"InvitationTemplate","description":"The email content sent with an invitation, so the wording matches the access the invitee is being given."},{"name":"MarketStatus","description":"Whether the market is currently open, and the trading hours that decide it."},{"name":"Messaging","description":"Server-Sent Events. A single stream carrying live prices, market status and Guard updates, multiplexed by subscription so one connection serves the whole session."},{"name":"Offboarding","description":"Winding down a user — disable them, re-enable them, or permanently erase their personal data."},{"name":"Payment Rails","description":"Payment rail availability and configuration"},{"name":"PriceHistory","description":"Historical exchange rate series for charting and analysis, with the sources and symbols available."},{"name":"ProblemTypes","description":"The catalogue of problem types this API can return. Every error body carries a `type` that resolves to one of these."},{"name":"RegulatedEntity","description":"Regulated Entities — the licensed payment firms that offer CurrencyGuard to their customers. Covers the entity's own profile, branding and configuration."},{"name":"Reports","description":"Reporting extracts covering your regulated entity's activity."},{"name":"SalesUserManagement","description":"Sales user accounts — the people at an Introducing Broker who act on behalf of Companies."},{"name":"ServerTime","description":"The server's current time. Use it to align quote expiry and settlement-window checks with the clock the server enforces."},{"name":"SpotRates","description":"Live spot exchange rates for the currency pairs you are configured to trade."},{"name":"SubscriptionMessages","description":"Message shapes carried on the event and SSE streams. These endpoints are never called; they exist so the message types appear in this specification and in generated clients."},{"name":"TradeExport","description":"Bulk export of trade data as a file, scoped to what your role can see."},{"name":"TradingCalendar","description":"Market holidays and trading days, which decide valid trade and settlement dates."},{"name":"UIConfig","description":"Runtime configuration for CurrencyGuard-hosted front ends. Not needed for API integration."},{"name":"User","description":"User accounts, their permissions, and the signed-in user's own profile and avatar."},{"name":"Webhooks","description":"Event delivery to your systems. Register an endpoint and CurrencyGuard POSTs batches of trading and onboarding events to it as they occur, signed with a shared secret you can rotate. Delivery is checkpointed, so a subscription can be replayed from a known position after an outage."}],"paths":{"/api-regulated/v1/api-clients":{"get":{"tags":["ApiClient"],"summary":"List the API clients for your regulated entity","description":"**Required entitlement:** `regulated.api-clients.canManageApiClients`  \n_Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration_","operationId":"listApiClientsRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiClientDTO"}}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageApiClients"]}],"x-entitlement":"regulated.api-clients.canManageApiClients"},"post":{"tags":["ApiClient"],"summary":"Create an API client and receive its secret","description":"The client secret is returned ONCE, in this response, and cannot be retrieved afterwards. Store it before moving on; if it is lost, rotate the secret to obtain a new one.\n\n**Required entitlement:** `regulated.api-clients.canManageApiClients`  \n_Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration_","operationId":"createApiClientRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiClientRequestDTO"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiClientWithSecretDTO"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageApiClients"]}],"x-entitlement":"regulated.api-clients.canManageApiClients"}},"/api-regulated/v1/api-clients/{apiClientId}":{"get":{"tags":["ApiClient"],"summary":"Get one API client","description":"**Required entitlement:** `regulated.api-clients.canManageApiClients`  \n_Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration_","operationId":"getApiClientRegulated","parameters":[{"name":"apiClientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiClientDTO"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageApiClients"]}],"x-entitlement":"regulated.api-clients.canManageApiClients"},"delete":{"tags":["ApiClient"],"summary":"Delete an API client","description":"Permanently revokes the credentials. Any integration still using them begins failing authentication at once.\n\n**Required entitlement:** `regulated.api-clients.canManageApiClients`  \n_Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration_","operationId":"deleteApiClientRegulated","parameters":[{"name":"apiClientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageApiClients"]}],"x-entitlement":"regulated.api-clients.canManageApiClients"}},"/api-regulated/v1/api-clients/{apiClientId}/rotate-secret":{"post":{"tags":["ApiClient"],"summary":"Rotate an API client secret","description":"Issues a new secret and returns it once. The previous secret stops working immediately, so deploy the new one before rotating.\n\n**Required entitlement:** `regulated.api-clients.canManageApiClients`  \n_Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration_","operationId":"rotateApiClientSecretRegulated","parameters":[{"name":"apiClientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiClientWithSecretDTO"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageApiClients"]}],"x-entitlement":"regulated.api-clients.canManageApiClients"}},"/api-regulated/v1/best-worst-historic-fx-performance":{"get":{"tags":["HistoricPerformance"],"summary":"Analyze best and worst historical FX performance","description":"Analyzes historical FX rate data to identify the best and worst performing periods that match the duration from today to the settlement date. The analysis looks back through 25 years of historical data to provide insights into potential volatility scenarios.","operationId":"analyzeRegulated","parameters":[{"name":"settlementDate","in":"query","description":"Settlement date for the analysis period, representing the end of the target duration","required":true,"schema":{"type":"string","description":"Settlement date for the analysis period, representing the end of the target duration","example":"2025-07-01T00:00:00Z"},"example":"2025-07-01T00:00:00Z"},{"name":"baseCurrency","in":"query","description":"Base currency (domestic currency)","required":true,"schema":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency (domestic currency)","example":"GBP"},"example":"GBP"},{"name":"quoteCurrency","in":"query","description":"Quote currency (foreign currency)","required":true,"schema":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency (foreign currency)","example":"USD"},"example":"USD"},{"name":"payReceive","in":"query","description":"Indicates whether this is a pay or receive scenario","required":true,"schema":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether this is a pay or receive scenario","example":"RECEIVE","enum":["PAY","RECEIVE"]},"example":"RECEIVE"},{"name":"foreignAmount","in":"query","description":"Amount in the foreign (quote) currency","required":true,"schema":{"minimum":0,"type":"string","description":"Amount in the foreign (quote) currency","example":50000},"example":50000},{"name":"guardAmount","in":"query","description":"Guard amount in the base (domestic) currency. When provided, delta amounts are calculated relative to this protected amount. Typically the guardAmount from a Guard quote.","required":false,"schema":{"minimum":0,"type":"string","description":"Guard amount in the base (domestic) currency. When provided, delta amounts are calculated relative to this protected amount. Typically the guardAmount from a Guard quote.","example":36232},"example":36232}],"responses":{"200":{"description":"Analysis completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BestWorstHistoricFxPerformanceResponseDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Unprocessable entity - invalid currency codes or dates — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/calendar-dates/calendar/{calendarCode}":{"get":{"tags":["CalendarDate"],"summary":"Get calendar dates by calendar code","description":"Returns holidays and special dates for a specific calendar, optionally filtered by date range","operationId":"getCalendarDatesByCalendarCodeRegulated","parameters":[{"name":"calendarCode","in":"path","description":"Calendar code (e.g., GBLO, USNY)","required":true,"schema":{"type":"string"},"example":"GBLO"},{"name":"fromDate","in":"query","description":"Start date in ISO format (YYYY-MM-DD)","required":false,"schema":{"type":"string","format":"date"},"example":"2025-01-01"},{"name":"toDate","in":"query","description":"End date in ISO format (YYYY-MM-DD)","required":false,"schema":{"type":"string","format":"date"},"example":"2025-12-31"}],"responses":{"200":{"description":"Calendar dates retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDateDTO"}}}}},"400":{"description":"Invalid date range — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/calendars":{"get":{"tags":["Calendar"],"summary":"Get all calendars","description":"Returns a list of all financial center calendars with their business day rules and weekend configurations","operationId":"getAllCalendarsRegulated","responses":{"200":{"description":"Successfully retrieved calendars","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDTO"}}}}},"403":{"description":"Access denied — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/calendars/{calendarCode}":{"get":{"tags":["Calendar"],"summary":"Get calendar by code","description":"Returns details for a specific financial center calendar including weekend rules and metadata","operationId":"getCalendarByCodeRegulated","parameters":[{"name":"calendarCode","in":"path","description":"Calendar code (e.g., GBLO, USNY)","required":true,"schema":{"type":"string"},"example":"GBLO"}],"responses":{"200":{"description":"Calendar found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarDTO"}}}},"403":{"description":"Access denied — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Calendar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/companies/{companyId}/customers":{"get":{"tags":["CustomerManagement"],"summary":"Get all customers for company","description":"Returns a list of all customers belonging to the specified company within the regulated entity.","operationId":"getAllCustomersForCompanyRegulated","parameters":[{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"bbbbbbbb-bb11-4001-8000-000000000000"}],"responses":{"200":{"description":"Customers retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found in regulated entity — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["CustomerManagement"],"summary":"Create a new customer for company","description":"Creates a new customer for the specified company within the regulated entity.\n\n**Required entitlement:** `regulated.customers.canModifyCustomer`  \n_Entitles the regulated user to create and update customer accounts within their customer companies_","operationId":"createCustomerForCompanyRegulated","parameters":[{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"bbbbbbbb-bb11-4001-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTOCreate"}}},"required":true},"responses":{"201":{"description":"Customer created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid request body or business validation failed — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - no access to regulated entity or company — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found in regulated entity — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.customers.canModifyCustomer"]}],"x-entitlement":"regulated.customers.canModifyCustomer"}},"/api-regulated/v1/companies/{companyId}/customers/{customerId}":{"get":{"tags":["CustomerManagement"],"summary":"Get customer by ID","description":"Returns a specific customer by ID, ensuring it belongs to the specified company within the regulated entity.","operationId":"getCustomerByIdInCompanyRegulated","parameters":[{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"bbbbbbbb-bb11-4001-8000-000000000000"},{"name":"customerId","in":"path","description":"Customer ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440000"}],"responses":{"200":{"description":"Customer retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid customer ID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - no access to regulated entity or company — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Customer not found in the specified company — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["CustomerManagement"],"summary":"Update customer in company","description":"Updates an existing customer, ensuring it belongs to the specified company within the regulated entity.\n\n**Required entitlement:** `regulated.customers.canModifyCustomer`  \n_Entitles the regulated user to create and update customer accounts within their customer companies_","operationId":"updateCustomerInCompanyRegulated","parameters":[{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"bbbbbbbb-bb11-4001-8000-000000000000"},{"name":"customerId","in":"path","description":"Customer ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Customer updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid customer ID format or request body — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - no access to regulated entity or company — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Customer not found in the specified company — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Optimistic locking conflict - customer was modified by another user — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.customers.canModifyCustomer"]}],"x-entitlement":"regulated.customers.canModifyCustomer"}},"/api-regulated/v1/companies/{companyId}/customers/{customerId}/avatar":{"get":{"tags":["CustomerManagement"],"summary":"Download customer avatar","description":"Download the avatar for a customer within the specified company and regulated entity. Regulated users can only access avatars of customers within their regulated entity scope.","operationId":"downloadCustomerAvatarRegulated","parameters":[{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"bbbbbbbb-bb11-4001-8000-000000000000"},{"name":"customerId","in":"path","description":"Customer ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440000"}],"responses":{"200":{"description":"Avatar retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Customer or avatar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/confirmation-templates":{"get":{"tags":["ConfirmationTemplate"],"summary":"List confirmation templates for this regulated entity","operationId":"getConfirmationTemplatesRegulated","responses":{"200":{"description":"Templates retrieved","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfirmationTemplateDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["ConfirmationTemplate"],"summary":"Create a confirmation template for this regulated entity","operationId":"createConfirmationTemplateRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationTemplateDTOCreate"}}},"required":true},"responses":{"200":{"description":"Template created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConfirmationTemplateDTO"}}}},"400":{"description":"Invalid request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/confirmation-templates/{id}":{"put":{"tags":["ConfirmationTemplate"],"summary":"Update a confirmation template for this regulated entity","operationId":"updateConfirmationTemplateRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationTemplateDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Template updated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConfirmationTemplateDTO"}}}},"400":{"description":"Invalid request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currencies":{"get":{"tags":["Currency"],"summary":"Get all currencies","description":"Returns a list of currencies supported by the platform. By default, only returns currencies used in active currency pairs (GBP, EUR, USD). Set activeOnly=false to see all configured currencies.","operationId":"getAllCurrenciesRegulated","parameters":[{"name":"activeOnly","in":"query","description":"Filter to only currencies in active trading pairs (default: true)","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Currencies retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currencies/{code}":{"get":{"tags":["Currency"],"summary":"Get currency","description":"Fetches detailed information for a specific currency identified by its ISO code.","operationId":"getCurrencyByCodeRegulated","parameters":[{"name":"code","in":"path","description":"Currency code","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Currency retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyDTO"}}}},"400":{"description":"Invalid code — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Currency not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currency-pairs":{"get":{"tags":["CurrencyPair"],"summary":"Get all currency pairs","description":"Returns currency pairs with their pip precision information. Use 'active' to filter by status and 'guardEnabled' to list only the pairs Guards can be quoted on.","operationId":"getAllCurrencyPairsRegulated","parameters":[{"name":"active","in":"query","description":"Filter by active status. If not provided, returns all currency pairs","required":false,"schema":{"type":"string"},"example":true},{"name":"guardEnabled","in":"query","description":"Filter to the pairs Guards can be quoted on (true) or the rate-only pairs (false). If not provided, both are returned","required":false,"schema":{"type":"string"},"example":true}],"responses":{"200":{"description":"Successfully retrieved currency pairs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyPairDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currency-pairs/active":{"get":{"tags":["CurrencyPair"],"summary":"Get active currency pairs","description":"Returns only the currency pairs that are marked as active for trading","operationId":"getActiveCurrencyPairsRegulated","responses":{"200":{"description":"Successfully retrieved active currency pairs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyPairDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currency-pairs/{currencyPair}":{"get":{"tags":["CurrencyPair"],"summary":"Get currency pair by currency pair code","description":"Returns currency pair information for a 6-character currency pair code (e.g., GBPUSD)","operationId":"getCurrencyPairByCurrencyPairRegulated","parameters":[{"name":"currencyPair","in":"path","description":"6-character currency pair code","required":true,"schema":{"type":"string"},"example":"GBPUSD"}],"responses":{"200":{"description":"Successfully retrieved currency pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyPairDTO"}}}},"400":{"description":"Invalid currency pair format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Currency pair not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currencyguard-companies":{"get":{"tags":["CurrencyguardCompany"],"summary":"Get all CurrencyGuard companies","description":"Returns a list of all CurrencyGuard companies (typically one company). Available to regulated and customer users for viewing company information.","operationId":"getAllCurrencyguardCompaniesRegulated","responses":{"200":{"description":"Companies retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyguardCompanyDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/currencyguard-companies/{currencyguardCompanyId}":{"get":{"tags":["CurrencyguardCompany"],"summary":"Get CurrencyGuard company by ID","description":"Retrieves a specific CurrencyGuard company by its ID. Available to regulated and customer users.","operationId":"getCurrencyguardCompanyByIdRegulated","parameters":[{"name":"currencyguardCompanyId","in":"path","description":"CurrencyGuard Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"CurrencyGuard company retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyguardCompanyDTO"}}}},"400":{"description":"Invalid company ID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"CurrencyGuard company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/documents":{"get":{"tags":["Documents"],"summary":"List all documents in scope","description":"Returns every document the caller can see, each with its owning entity id so callers can group by entity. Intended for search and indexing; use the per-entity documents endpoint when only one entity is needed.","operationId":"getAllDocumentsRegulated","responses":{"200":{"description":"Documents listed","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/entitlements-templates":{"get":{"tags":["EntitlementsTemplate"],"summary":"Get all entitlements templates for regulated and customer roles","description":"Returns a list of entitlements templates for regulated and customer roles only. Regulated users cannot view internal templates. Can be filtered to show only active templates and/or templates for specific roles.","operationId":"getAllTemplatesRegulated","parameters":[{"name":"activeOnly","in":"query","description":"Filter to show only active templates","required":false,"schema":{"type":"boolean","default":false}},{"name":"role","in":"query","description":"Filter templates by role (REST_REGULATED, REST_SALES, REST_CUSTOMER)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Templates retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["EntitlementsTemplate"],"summary":"Create new entitlements template","description":"Creates a new entitlements template with the specified permissions for sales or customer roles. Cannot create internal templates.\n\n**Required entitlement:** `regulated.templates.canEditEntitlementTemplate`  \n_Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity_","operationId":"createTemplateRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTOCreate"}}},"required":true},"responses":{"201":{"description":"Template created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}},"400":{"description":"Invalid request data or template name already exists — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - cannot create internal templates — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.templates.canEditEntitlementTemplate"]}],"x-entitlement":"regulated.templates.canEditEntitlementTemplate"}},"/api-regulated/v1/entitlements-templates/entitlements":{"get":{"tags":["EntitlementsTemplate"],"summary":"Get all available entitlements","description":"Returns a list of all entitlement definitions available in the system. Internal entitlements are excluded for regulated and customer users. These can be used to build entitlements templates.","operationId":"getAllEntitlementsRegulated","responses":{"200":{"description":"Entitlements retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntitlementDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/entitlements-templates/entitlements/categories":{"get":{"tags":["EntitlementsTemplate"],"summary":"Get entitlements grouped by category","description":"Returns entitlements organized by category (scope and functional area) for easier UI presentation. Only shows categories available to regulated and customer roles.","operationId":"getEntitlementsByCategoryRegulated","responses":{"200":{"description":"Entitlement categories retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntitlementCategoryDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/entitlements-templates/{id}":{"get":{"tags":["EntitlementsTemplate"],"summary":"Get entitlements template by ID","description":"Retrieves a specific entitlements template by its UUID. Regulated users can only access regulated and customer templates.","operationId":"getTemplateByIdRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}},"400":{"description":"Invalid UUID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - cannot access internal templates — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["EntitlementsTemplate"],"summary":"Update entitlements template","description":"Updates an existing entitlements template. Regulated users can only update regulated and customer templates. Template name uniqueness is validated.\n\n**Required entitlement:** `regulated.templates.canEditEntitlementTemplate`  \n_Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity_","operationId":"updateTemplateRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Template updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}},"400":{"description":"Invalid request data or template name already exists — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - cannot update internal templates — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.templates.canEditEntitlementTemplate"]}],"x-entitlement":"regulated.templates.canEditEntitlementTemplate"},"delete":{"tags":["EntitlementsTemplate"],"summary":"Deactivate entitlements template","description":"Deactivates (tombstones) an entitlements template. Regulated users can only deactivate regulated and customer templates. The template will no longer be available for assignment but existing references are preserved.\n\n**Required entitlement:** `regulated.templates.canEditEntitlementTemplate`  \n_Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity_","operationId":"deactivateTemplateRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template deactivated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}},"400":{"description":"Invalid UUID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - cannot deactivate internal templates — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Template is already inactive — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.templates.canEditEntitlementTemplate"]}],"x-entitlement":"regulated.templates.canEditEntitlementTemplate"}},"/api-regulated/v1/entitlements-templates/{id}/activate":{"post":{"tags":["EntitlementsTemplate"],"summary":"Reactivate entitlements template","description":"Reactivates a previously deactivated entitlements template, making it available for assignment again. Regulated users can only reactivate regulated and customer templates.\n\n**Required entitlement:** `regulated.templates.canEditEntitlementTemplate`  \n_Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity_","operationId":"activateTemplateRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template reactivated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementsTemplateDTO"}}}},"400":{"description":"Invalid UUID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - cannot reactivate internal templates — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Template is already active — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.templates.canEditEntitlementTemplate"]}],"x-entitlement":"regulated.templates.canEditEntitlementTemplate"}},"/api-regulated/v1/fx-spot-prices":{"get":{"tags":["SpotRates"],"summary":"Get spot FX prices for all active currency pairs","description":"Returns current spot FX prices (bid, ask, mid rates) for all currency pairs that are currently active in the system. Each price includes state information (VALID/ERROR) and metadata about the price source. Response is returned as a JSON array containing all active currency pairs.","operationId":"getAllSpotPricesRegulated","responses":{"200":{"description":"Spot prices retrieved successfully. Returns a JSON array of FXPriceStateDTO objects, one for each active currency pair.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FXPriceStateDTO"}},"examples":{"Multiple Spot Prices":{"description":"Multiple Spot Prices","value":[{"state":"VALID","timestamp":"2024-03-01T14:30:15.123Z","subscriptionSource":"DEFAULT","emissionSource":"CURRENCYGUARD","value":{"symbol":"GBPUSD","timestamp":"2024-03-01T14:30:15.123Z","bid":1.2645,"ask":1.2647,"mid":1.2646}},{"state":"VALID","timestamp":"2024-03-01T14:30:16.456Z","subscriptionSource":"DEFAULT","emissionSource":"CURRENCYGUARD","value":{"symbol":"EURUSD","timestamp":"2024-03-01T14:30:16.456Z","bid":1.08235,"ask":1.08255,"mid":1.08245}}]}}}}},"401":{"description":"Not authenticated - valid JWT token required — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires REGULATED or INTERNAL role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error - internal processing failure — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/fx-spot-prices/{currencyPair}":{"get":{"tags":["SpotRates"],"summary":"Get spot FX price","description":"Returns the current spot FX price containing bid, ask, and mid rates for the specified currency pair. The response includes state information (VALID/ERROR) and metadata about the price source. Prices are typically updated in real-time from market data providers.","operationId":"getSpotPriceRegulated","parameters":[{"name":"currencyPair","in":"path","description":"Currency pair in 6-character format: 3-letter base currency code followed by 3-letter quote currency code (e.g., GBPUSD for British Pound vs US Dollar, EURUSD for Euro vs US Dollar). Case insensitive.","required":true,"schema":{"type":"string"},"example":"GBPUSD"}],"responses":{"200":{"description":"Spot price retrieved successfully. Returns FXPriceStateDTO with current bid/ask/mid rates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FXPriceStateDTO"},"examples":{"GBPUSD Spot Price":{"description":"GBPUSD Spot Price","value":{"state":"VALID","timestamp":"2024-03-01T14:30:15.123Z","subscriptionSource":"DEFAULT","emissionSource":"CURRENCYGUARD","value":{"symbol":"GBPUSD","timestamp":"2024-03-01T14:30:15.123Z","bid":1.2645,"ask":1.2647,"mid":1.2646}}}}}}},"400":{"description":"Invalid currency pair format - must be 6 characters (3-letter base + 3-letter quote currency) — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated - valid JWT token required — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires REGULATED or INTERNAL role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Currency pair not found or not active in the system — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error - internal processing failure — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guard-quotes/quote-guard":{"post":{"tags":["GuardQuote"],"summary":"Create a guard quote","description":"Creates a new guard quote for the regulated entity and persists it to the database.\n\n**Required entitlement:** `regulated.risk-management.canBuyGuard`  \n_Entitles the regulated user to enter guard trades for their customers_","operationId":"quoteGuardRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedGuardQuoteDTO"}}},"required":true},"responses":{"201":{"description":"Guard quote created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardQuoteStateDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Quote rejected by a business rule\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/supplied-mid-off-market`](/problems/guard/supplied-mid-off-market/) | The supplied market mid deviates from CurrencyGuard's mid by more than the configured tolerance |\n| [`guard/pair-not-configured`](/problems/guard/pair-not-configured/) | The currency pair lacks configuration required to price or validate the request |\n| [`guard/guard-duration-out-of-range`](/problems/guard/guard-duration-out-of-range/) | The requested Guard duration is outside the permitted minimum and maximum tenor |\n| [`guard/sales-margin-mismatch`](/problems/guard/sales-margin-mismatch/) | A sales margin rate and a sales margin amount were both supplied and they do not agree within tolerance |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"suppliedMidOffMarket":{"summary":"Supplied Mid Off Market","description":"Send a mid within `toleranceBps` of `currencyguardMid`, or omit it and let CurrencyGuard price off its own mid.","value":{"type":"https://developer.currencyguard.com/problems/guard/supplied-mid-off-market","title":"Supplied Mid Off Market","status":422,"detail":"The supplied market mid is outside CurrencyGuard's tolerance","suppliedMid":"<The mid supplied by the caller>","currencyguardMid":"<CurrencyGuard's own mid for the pair>","deviationBps":"<The deviation between them, in basis points>","toleranceBps":"<The permitted tolerance for the pair, in basis points>","currencyPair":"<The currency pair>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"pairNotConfigured":{"summary":"Currency Pair Not Configured","description":"Not retryable by the caller - the pair needs configuring. Contact CurrencyGuard.","value":{"type":"https://developer.currencyguard.com/problems/guard/pair-not-configured","title":"Currency Pair Not Configured","status":422,"detail":"No supplied-mid tolerance is configured for GBPUSD","currencyPair":"<The currency pair lacking configuration>","missingConfiguration":"<What is missing, e.g. supplied-mid tolerance>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"guardDurationOutOfRange":{"summary":"Guard Duration Out Of Range","description":"Choose a settlement window end date between `earliestPermitted` and `latestPermitted`.","value":{"type":"https://developer.currencyguard.com/problems/guard/guard-duration-out-of-range","title":"Guard Duration Out Of Range","status":422,"detail":"Settlement window end date must be at least 5 business days after guard period start date","bound":"<Which bound was breached: minimum or maximum>","minimumBusinessDays":"<The minimum tenor in business days, when bound is minimum>","maximumBusinessDays":"<The maximum tenor in business days, when bound is maximum>","earliestPermitted":"<The earliest permitted settlement window end date>","latestPermitted":"<The latest permitted settlement window end date>","provided":"<The settlement window end date requested>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"salesMarginMismatch":{"summary":"Sales Margin Mismatch","description":"Send only salesMarginRate or only salesMargin, not both, unless they agree to within 0.01.","value":{"type":"https://developer.currencyguard.com/problems/guard/sales-margin-mismatch","title":"Sales Margin Mismatch","status":422,"detail":"Sales margin mismatch: provided amount 250.00 doesn't match calculated amount 240.00 from rate 0.0024","providedSalesMargin":"<The sales margin amount supplied>","expectedSalesMargin":"<The amount implied by the supplied rate>","salesMarginRate":"<The sales margin rate supplied>","difference":"<The absolute difference between the two>","tolerance":"<The permitted difference>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/supplied-mid-off-market","guard/pair-not-configured","guard/guard-duration-out-of-range","guard/sales-margin-mismatch"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"503":{"description":"Market data required to price the quote is not currently available. Retryable; nothing about the request needs to change.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`market-data/market-data-unavailable`](/problems/market-data/market-data-unavailable/) | The market data required to price or book the request is not currently available |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"marketDataUnavailable":{"summary":"Market Data Unavailable","description":"Retry shortly. Nothing about the request needs to change; a feed has not delivered or has gone stale.","value":{"type":"https://developer.currencyguard.com/problems/market-data/market-data-unavailable","title":"Market Data Unavailable","status":503,"detail":"No spot price available for GBPUSD","currencyPair":"<The currency pair whose data is missing>","dataType":"<Which datum is missing, e.g. spot, volatility, interest-rate>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["market-data/market-data-unavailable"]}},"security":[{"entitlementsScheme":["regulated.risk-management.canBuyGuard"]}],"x-entitlement":"regulated.risk-management.canBuyGuard"}},"/api-regulated/v1/guard-quotes/smart-parse":{"post":{"tags":["GuardQuote"],"summary":"Parse natural language guard transaction text using AI","description":"Parses a natural language description of a guard transaction into structured fields\nusing LLM integration (Google Gemini).\n\n**Example Request:**\n```json\n{\n  \"text\": \"Thames Trading needs to buy €650k against GBP in 45 days for supplier invoice TT-2025-443 with 25 basis points and they want to pay later\"\n}\n```\n\n**Example Response:**\n```json\n{\n  \"payReceive\": \"PAY\",\n  \"foreignCurrency\": \"EUR\",\n  \"guardCurrency\": \"GBP\",\n  \"foreignAmount\": 650000,\n  \"guardSettlementWindowTo\": \"2026-01-06T00:00:00Z\",\n  \"salesMarginRate\": 0.0025,\n  \"externalRef\": \"TT-2025-443\",\n  \"companyName\": \"Thames Trading\",\n  \"isPayLater\": true,\n  \"amountInputMode\": \"foreign\",\n  \"reason\": \"Supplier invoice TT-2025-443\"\n}\n```\n\n**What gets parsed:**\n- Direction: \"buy\" → PAY\n- Amount: \"€650k\" → 650000 (foreignAmount)\n- Amount mode: \"foreign\" (indicates foreignAmount was specified, not targetGuardAmount)\n- Currency pair: \"€\" → EUR, \"against GBP\" → GBP\n- Settlement: \"in 45 days\" → calculated date\n- Margin: \"25 basis points\" → 0.0025 (decimal rate)\n- Reference: \"invoice TT-2025-443\" → TT-2025-443\n- Company/Customer: Returned as strings (companyName, customerName, customerEmail) for client-side fuzzy matching\n- Payment terms: \"pay later\" → true\n- Context: \"supplier invoice\" → extracted to reason field\n\nThe parsed fields can then be used to pre-populate a guard quote request.\nClient performs fuzzy matching against their company/customer lists.\n","operationId":"smartParseGuardTextRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartParseGuardQuoteRequestDTO"}}},"required":true},"responses":{"200":{"description":"Text successfully parsed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartParseGuardQuoteResponseDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Text cannot be parsed — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guard-quotes/{quoteId}/buy-guard":{"post":{"tags":["GuardQuote"],"summary":"Buy guard from quote","description":"Creates a new guard from a previously generated quote and initiates the purchase process.\n\n**Required entitlement:** `regulated.risk-management.canBuyGuard`  \n_Entitles the regulated user to enter guard trades for their customers_","operationId":"buyGuardFromQuoteRegulated","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Guard created and purchase initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardDTO"}}}},"400":{"description":"Invalid quote ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Quote not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Quote expired or already traded\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-quote/quote-expired`](/problems/guard-quote/quote-expired/) | The quote has passed its time to live and can no longer be traded; request a new quote |\n| [`guard-quote/quote-already-traded`](/problems/guard-quote/quote-already-traded/) | The quote has already been used to create a Guard and cannot be traded again |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"quoteExpired":{"summary":"Quote Expired","description":"Request a new quote and buy against that. Retrying with the same quote will never succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/quote-expired","title":"Quote Expired","status":409,"detail":"Quote has expired (age: 45 seconds, max: 30 seconds)","ageSeconds":"<How long ago the quote was struck>","ttlSeconds":"<The quote's permitted time to live>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"quoteAlreadyTraded":{"summary":"Quote Already Traded","description":"Do not retry. The Guard this quote produced already exists - look it up rather than buying again. Usually a duplicate submission.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/quote-already-traded","title":"Quote Already Traded","status":409,"detail":"Quote has already been traded","quoteStatus":"<The quote's current status>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-quote/quote-expired","guard-quote/quote-already-traded"]},"422":{"description":"Quote built on failed market data\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-quote/pricing-failed`](/problems/guard-quote/pricing-failed/) | Pricing operation failed due to market data or calculation issues |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"pricingFailed":{"summary":"Pricing Calculation Failed","description":"Request a fresh quote. The existing one cannot be used.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/pricing-failed","title":"Pricing Calculation Failed","status":422,"detail":"Missing volatility data for currency pair","pricingErrors":"<Why the quote's market data was unusable. Named distinctly from the field-level `validationErrors` array, which is a different shape carrying a different thing.>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-quote/pricing-failed"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canBuyGuard"]}],"x-entitlement":"regulated.risk-management.canBuyGuard"}},"/api-regulated/v1/guard-quotes/{quoteId}/buy-guard-extension":{"post":{"tags":["GuardQuote"],"summary":"Buy guard extension from quote","description":"Purchases a guard extension from a previously generated extension quote.\n\n**Required entitlement:** `regulated.risk-management.canExtendGuard`  \n_Entitles the regulated user to extend guard position expiration dates for their customers_","operationId":"buyGuardExtensionFromQuoteRegulated","parameters":[{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Guard extension purchased and applied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardDTO"}}}},"400":{"description":"Invalid quote ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Quote not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Quote expired or already traded\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-quote/quote-expired`](/problems/guard-quote/quote-expired/) | The quote has passed its time to live and can no longer be traded; request a new quote |\n| [`guard-quote/quote-already-traded`](/problems/guard-quote/quote-already-traded/) | The quote has already been used to create a Guard and cannot be traded again |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"quoteExpired":{"summary":"Quote Expired","description":"Request a new quote and buy against that. Retrying with the same quote will never succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/quote-expired","title":"Quote Expired","status":409,"detail":"Quote has expired (age: 45 seconds, max: 30 seconds)","ageSeconds":"<How long ago the quote was struck>","ttlSeconds":"<The quote's permitted time to live>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"quoteAlreadyTraded":{"summary":"Quote Already Traded","description":"Do not retry. The Guard this quote produced already exists - look it up rather than buying again. Usually a duplicate submission.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/quote-already-traded","title":"Quote Already Traded","status":409,"detail":"Quote has already been traded","quoteStatus":"<The quote's current status>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-quote/quote-expired","guard-quote/quote-already-traded"]},"422":{"description":"Quote built on failed market data\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-quote/pricing-failed`](/problems/guard-quote/pricing-failed/) | Pricing operation failed due to market data or calculation issues |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"pricingFailed":{"summary":"Pricing Calculation Failed","description":"Request a fresh quote. The existing one cannot be used.","value":{"type":"https://developer.currencyguard.com/problems/guard-quote/pricing-failed","title":"Pricing Calculation Failed","status":422,"detail":"Missing volatility data for currency pair","pricingErrors":"<Why the quote's market data was unusable. Named distinctly from the field-level `validationErrors` array, which is a different shape carrying a different thing.>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-quote/pricing-failed"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canExtendGuard"]}],"x-entitlement":"regulated.risk-management.canExtendGuard"}},"/api-regulated/v1/guards":{"get":{"tags":["Guard"],"summary":"Get all guards","description":"Returns a list of all guards associated with the regulated entity.","operationId":"getGuardsRegulated","parameters":[{"name":"status","in":"query","description":"Filter guards by status","required":false,"schema":{"type":"string","enum":["ERROR","CANCELLED","PENDING","AWAITING_FEE","ACTIVE","COMPLETE","LAPSED","VOID","EXTENDED"]}}],"responses":{"200":{"description":"Guards retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GuardDTO"}}}}},"400":{"description":"Invalid parameters — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/request-funded-settlements":{"post":{"tags":["GuardSettlement"],"summary":"Request funded settlements","description":"Raises one or more funded settlement requests, all of them or none. Each line becomes a settlement in AWAITING_FUNDING that claims its slice of the Guard immediately; no rate is struck until the client's money arrives and CurrencyGuard executes. Lines naming the same Guard are summed before the available amount is checked. More than one Guard shares a batch reference, so the whole request can be paid with a single payment, and must then be one company settling in one currency.\n\n**Required entitlement:** `regulated.risk-management.canSettleGuard`  \n_Entitles the regulated user to settle existing guard positions for their customers_","operationId":"requestFundedSettlementsRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedRequestFundedSettlements"}}},"required":true},"responses":{"201":{"description":"Funded settlement requests raised","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Guard is not in a settleable status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/invalid-state-transition`](/problems/guard/invalid-state-transition/) | Operation cannot be performed in the current resource state |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"invalidStateTransition":{"summary":"Invalid State Transition","description":"Re-read the Guard and offer only the actions its current status permits. Retrying unchanged will not succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard/invalid-state-transition","title":"Invalid State Transition","status":409,"detail":"Cannot activate a completed guard","operation":"<The operation that was attempted, e.g. settled, cancelled, voided>","guardStatus":"<The Guard's current status>","allowedStatuses":"<The statuses in which the operation would have been permitted>","reasons":"<Present instead of allowedStatuses when the rejection is expressed as validation reasons>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/invalid-state-transition"]},"422":{"description":"Request rejected by a business rule\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-settlement/outside-settlement-window`](/problems/guard-settlement/outside-settlement-window/) | Settlement was attempted outside the Guard's permitted settlement (drawdown) window |\n| [`guard-settlement/settlement-exceeds-remaining`](/problems/guard-settlement/settlement-exceeds-remaining/) | The requested settlement amount is greater than the Guard's unsettled balance |\n| [`guard-settlement/funded-request-exceeds-limit`](/problems/guard-settlement/funded-request-exceeds-limit/) | A funded settlement request asks for more than the per-request ceiling for this regulated entity |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"outsideSettlementWindow":{"summary":"Outside Settlement Window","description":"Settle between settlementWindowFrom and settlementWindowTo inclusive. Tell the user when the window opens.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/outside-settlement-window","title":"Outside Settlement Window","status":422,"detail":"Settlement is only permitted within the settlement window (2026-09-01 to 2026-10-01)","settlementWindowFrom":"<First business date on which settlement is permitted>","settlementWindowTo":"<Last business date on which settlement is permitted>","businessDate":"<The business date the request was evaluated against>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"settlementExceedsRemaining":{"summary":"Settlement Exceeds Remaining Amount","description":"Retry with an amount no greater than `unsettled`, or offer to settle the remaining balance in full.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/settlement-exceeds-remaining","title":"Settlement Exceeds Remaining Amount","status":422,"detail":"Settlement amount (50000) exceeds unsettled balance (20000)","requested":"<The settlement amount requested>","unsettled":"<The Guard's remaining unsettled balance>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"fundedRequestExceedsLimit":{"summary":"Funded Request Exceeds Limit","description":"Split the request into smaller ones, or ask CurrencyGuard to raise the ceiling for this regulated entity.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/funded-request-exceeds-limit","title":"Funded Request Exceeds Limit","status":422,"detail":"A funded settlement request may not exceed 250000 GBP (requested: 400000)","requested":"<The total the client would be asked to send, in guard currency>","limit":"<The configured per-request ceiling>","currency":"<The guard currency both figures are in>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-settlement/outside-settlement-window","guard-settlement/settlement-exceeds-remaining","guard-settlement/funded-request-exceeds-limit"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canSettleGuard"]}],"x-entitlement":"regulated.risk-management.canSettleGuard"}},"/api-regulated/v1/guards/{guardId}":{"get":{"tags":["Guard"],"summary":"Get guard details","description":"Retrieves detailed information for a specific guard.","operationId":"getGuardByIdRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Guard retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardDTO"}}}},"400":{"description":"Invalid ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/calculate-cancellation-refund":{"get":{"tags":["Guard"],"summary":"Calculate guard cancellation refund","description":"Calculates the refund amount and details for cancelling a guard based on guard age and maturity period.","operationId":"calculateCancellationRefundRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancellation refund calculated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardCancellationRefundDTO"}}}},"400":{"description":"Invalid guard ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/cancel-guard":{"post":{"tags":["Guard"],"summary":"Cancel guard","description":"Cancels a guard and creates a settlement for hedge unwinding. Refund amount is calculated based on guard age and maturity, minus the sales margin. Guards with hedges (ACTIVE status) will create a PENDING_SELL option for trader confirmation. Guards without hedges will be immediately settled.\n\n**Required entitlement:** `regulated.risk-management.canBuyGuard`  \n_Entitles the regulated user to enter guard trades for their customers_","operationId":"cancelGuardRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelGuardRequestDTO"}}},"required":true},"responses":{"200":{"description":"Guard cancelled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelGuardResponseDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Guard cannot be cancelled in its current state\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/invalid-state-transition`](/problems/guard/invalid-state-transition/) | Operation cannot be performed in the current resource state |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"invalidStateTransition":{"summary":"Invalid State Transition","description":"Re-read the Guard and offer only the actions its current status permits. Retrying unchanged will not succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard/invalid-state-transition","title":"Invalid State Transition","status":409,"detail":"Cannot activate a completed guard","operation":"<The operation that was attempted, e.g. settled, cancelled, voided>","guardStatus":"<The Guard's current status>","allowedStatuses":"<The statuses in which the operation would have been permitted>","reasons":"<Present instead of allowedStatuses when the rejection is expressed as validation reasons>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/invalid-state-transition"]},"422":{"description":"Guard cannot be cancelled in current status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/sales-margin-exceeded`](/problems/guard/sales-margin-exceeded/) | The sales margin on the request exceeds the maximum permitted for the applicable zone or refund |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"salesMarginExceeded":{"summary":"Sales Margin Exceeded","description":"Reduce the margin to at most `maxMargin` (or `maximumRefund` on a cancellation) and retry.","value":{"type":"https://developer.currencyguard.com/problems/guard/sales-margin-exceeded","title":"Sales Margin Exceeded","status":422,"detail":"Sales margin exceeds maximum permitted margin in protection zone","zone":"<The applicable pricing zone: protection or savings. Absent on a cancellation refund>","salesMargin":"<The sales margin implied by the request>","maxMargin":"<The maximum permitted margin for that zone>","maximumRefund":"<On a cancellation, the maximum refund available>","marketRate":"<The prevailing market rate>","guardRate":"<The Guard's protected rate>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/sales-margin-exceeded"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"503":{"description":"Cancellation blocked while the market is closed\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`integration/service-unavailable`](/problems/integration/service-unavailable/) | External service dependency is unavailable or unresponsive |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"serviceUnavailable":{"summary":"Service Unavailable","description":"Transient. Retry when the dependency is available.","value":{"type":"https://developer.currencyguard.com/problems/integration/service-unavailable","title":"Service Unavailable","status":503,"detail":"Market data provider temporarily unavailable","marketStatusReason":"<Why the market or dependency is currently unavailable>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["integration/service-unavailable"]}},"security":[{"entitlementsScheme":["regulated.risk-management.canBuyGuard"]}],"x-entitlement":"regulated.risk-management.canBuyGuard"}},"/api-regulated/v1/guards/{guardId}/confirmation":{"get":{"tags":["GuardConfirmation"],"summary":"Download Guard confirmation PDF","description":"Generates and downloads a Guard confirmation PDF for regulated entity users. Use ?type=bilateral (default) for CGL↔PSP confirmations or ?type=client for PSP↔SME confirmations.","operationId":"downloadGuardConfirmationRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}},{"name":"type","in":"query","description":"Confirmation type: 'bilateral' (CGL↔PSP, default) or 'client' (PSP↔SME)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF generated","content":{"application/pdf":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"Invalid confirmation type — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard or template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/guard-settlements":{"get":{"tags":["GuardSettlement"],"summary":"Get guard settlements","description":"Returns all settlement records for a regulated entity guard.","operationId":"getGuardSettlementsRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Guard settlements retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}}},"400":{"description":"Invalid guard ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/guard-settlements/{settlementId}":{"get":{"tags":["GuardSettlement"],"summary":"Get guard settlement details","description":"Returns specific settlement for a regulated entity guard.","operationId":"getGuardSettlementByIdRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}},{"name":"settlementId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Guard settlement retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}},"400":{"description":"Invalid IDs — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard settlement not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/guard-settlements/{settlementId}/cancel-funding-request":{"post":{"tags":["GuardSettlement"],"summary":"Withdraw a funded settlement request","description":"Withdraws a request that has not been funded, freeing the slice of the Guard it claimed. The row is kept and moves to FUNDING_CANCELLED -- the slice is released by dropping out of the claimed total, not by writing an amount back. Refused once the money has arrived: from then on CurrencyGuard is holding client funds and is committed to executing.\n\n**Required entitlement:** `regulated.risk-management.canSettleGuard`  \n_Entitles the regulated user to settle existing guard positions for their customers_","operationId":"cancelFundingRequestRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}},{"name":"settlementId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedCancelFundingRequest"}}}},"responses":{"200":{"description":"Funding request withdrawn","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard settlement not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"No longer awaiting funding\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-settlement/funding-request-not-cancellable`](/problems/guard-settlement/funding-request-not-cancellable/) | Withdrawal was attempted on a funded settlement that is no longer awaiting the client's money |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"fundingRequestNotCancellable":{"summary":"Funding Request Not Cancellable","description":"Only a settlement in AWAITING_FUNDING can be withdrawn. Once funded, CurrencyGuard is holding the money and the desk is committed to executing; ask CurrencyGuard about a refund instead.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/funding-request-not-cancellable","title":"Funding Request Not Cancellable","status":"<The status it is actually in>","detail":"Settlement GSP1000104-S01 is in EXECUTION_PENDING and can no longer be withdrawn: only AWAITING_FUNDING can be","settlementId":"<The settlement withdrawal was attempted on>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-settlement/funding-request-not-cancellable"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canSettleGuard"]}],"x-entitlement":"regulated.risk-management.canSettleGuard"}},"/api-regulated/v1/guards/{guardId}/preview-guard-settlement":{"get":{"tags":["GuardSettlement"],"summary":"Preview a guard settlement","description":"Computes the zone, the route the drawer should offer, and the funding for settling a given foreign amount now. Writes nothing and fixes no rate.\n\n**Required entitlement:** `regulated.risk-management.canSettleGuard`  \n_Entitles the regulated user to settle existing guard positions for their customers_","operationId":"previewGuardSettlementRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}},{"name":"foreignAmount","in":"query","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Settlement preview calculated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardSettlementPreviewDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canSettleGuard"]}],"x-entitlement":"regulated.risk-management.canSettleGuard"}},"/api-regulated/v1/guards/{guardId}/price-guard":{"get":{"tags":["Guard"],"summary":"Calculate the price of a guard","description":"Calculates the price of the guard based on current rates.","operationId":"calculateGuardPriceRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Guard price calculated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardQuoteStateDTO"}}}},"400":{"description":"Invalid ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/guards/{guardId}/quote-guard-extension":{"post":{"tags":["Guard"],"summary":"Calculate a guard extension quote","description":"Calculates the cost of extending the guard based on current rates and extension parameters, and provides it as a quote with a time-to-live.\n\n**Required entitlement:** `regulated.risk-management.canExtendGuard`  \n_Entitles the regulated user to extend guard position expiration dates for their customers_","operationId":"calculateGuardExtensionQuoteRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardExtensionQuoteRequestDTO"}}},"required":true},"responses":{"200":{"description":"Guard extension quote calculated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardQuoteStateDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Quote rejected by a business rule\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/guard-duration-out-of-range`](/problems/guard/guard-duration-out-of-range/) | The requested Guard duration is outside the permitted minimum and maximum tenor |\n| [`guard/supplied-mid-off-market`](/problems/guard/supplied-mid-off-market/) | The supplied market mid deviates from CurrencyGuard's mid by more than the configured tolerance |\n| [`guard/pair-not-configured`](/problems/guard/pair-not-configured/) | The currency pair lacks configuration required to price or validate the request |\n| [`guard/sales-margin-mismatch`](/problems/guard/sales-margin-mismatch/) | A sales margin rate and a sales margin amount were both supplied and they do not agree within tolerance |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"guardDurationOutOfRange":{"summary":"Guard Duration Out Of Range","description":"Choose a settlement window end date between `earliestPermitted` and `latestPermitted`.","value":{"type":"https://developer.currencyguard.com/problems/guard/guard-duration-out-of-range","title":"Guard Duration Out Of Range","status":422,"detail":"Settlement window end date must be at least 5 business days after guard period start date","bound":"<Which bound was breached: minimum or maximum>","minimumBusinessDays":"<The minimum tenor in business days, when bound is minimum>","maximumBusinessDays":"<The maximum tenor in business days, when bound is maximum>","earliestPermitted":"<The earliest permitted settlement window end date>","latestPermitted":"<The latest permitted settlement window end date>","provided":"<The settlement window end date requested>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"suppliedMidOffMarket":{"summary":"Supplied Mid Off Market","description":"Send a mid within `toleranceBps` of `currencyguardMid`, or omit it and let CurrencyGuard price off its own mid.","value":{"type":"https://developer.currencyguard.com/problems/guard/supplied-mid-off-market","title":"Supplied Mid Off Market","status":422,"detail":"The supplied market mid is outside CurrencyGuard's tolerance","suppliedMid":"<The mid supplied by the caller>","currencyguardMid":"<CurrencyGuard's own mid for the pair>","deviationBps":"<The deviation between them, in basis points>","toleranceBps":"<The permitted tolerance for the pair, in basis points>","currencyPair":"<The currency pair>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"pairNotConfigured":{"summary":"Currency Pair Not Configured","description":"Not retryable by the caller - the pair needs configuring. Contact CurrencyGuard.","value":{"type":"https://developer.currencyguard.com/problems/guard/pair-not-configured","title":"Currency Pair Not Configured","status":422,"detail":"No supplied-mid tolerance is configured for GBPUSD","currencyPair":"<The currency pair lacking configuration>","missingConfiguration":"<What is missing, e.g. supplied-mid tolerance>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"salesMarginMismatch":{"summary":"Sales Margin Mismatch","description":"Send only salesMarginRate or only salesMargin, not both, unless they agree to within 0.01.","value":{"type":"https://developer.currencyguard.com/problems/guard/sales-margin-mismatch","title":"Sales Margin Mismatch","status":422,"detail":"Sales margin mismatch: provided amount 250.00 doesn't match calculated amount 240.00 from rate 0.0024","providedSalesMargin":"<The sales margin amount supplied>","expectedSalesMargin":"<The amount implied by the supplied rate>","salesMarginRate":"<The sales margin rate supplied>","difference":"<The absolute difference between the two>","tolerance":"<The permitted difference>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/guard-duration-out-of-range","guard/supplied-mid-off-market","guard/pair-not-configured","guard/sales-margin-mismatch"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"503":{"description":"Market data required to price the quote is not currently available. Retryable; nothing about the request needs to change.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`market-data/market-data-unavailable`](/problems/market-data/market-data-unavailable/) | The market data required to price or book the request is not currently available |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"marketDataUnavailable":{"summary":"Market Data Unavailable","description":"Retry shortly. Nothing about the request needs to change; a feed has not delivered or has gone stale.","value":{"type":"https://developer.currencyguard.com/problems/market-data/market-data-unavailable","title":"Market Data Unavailable","status":503,"detail":"No spot price available for GBPUSD","currencyPair":"<The currency pair whose data is missing>","dataType":"<Which datum is missing, e.g. spot, volatility, interest-rate>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["market-data/market-data-unavailable"]}},"security":[{"entitlementsScheme":["regulated.risk-management.canExtendGuard"]}],"x-entitlement":"regulated.risk-management.canExtendGuard"}},"/api-regulated/v1/guards/{guardId}/request-funded-settlement":{"post":{"tags":["GuardSettlement"],"summary":"Request a funded settlement for one Guard","description":"The same thing for a single Guard, returning one settlement rather than a list. A wrapper: it builds a one-line request and calls the same service method, so every check -- including the per-request ceiling -- exists in exactly one place and batching buys the caller no headroom. No batch reference, because a lone settlement already has its own.\n\n**Required entitlement:** `regulated.risk-management.canSettleGuard`  \n_Entitles the regulated user to settle existing guard positions for their customers_","operationId":"requestFundedSettlementRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedRequestFundedSettlement"}}},"required":true},"responses":{"201":{"description":"Funded settlement request raised","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Guard is not in a settleable status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/invalid-state-transition`](/problems/guard/invalid-state-transition/) | Operation cannot be performed in the current resource state |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"invalidStateTransition":{"summary":"Invalid State Transition","description":"Re-read the Guard and offer only the actions its current status permits. Retrying unchanged will not succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard/invalid-state-transition","title":"Invalid State Transition","status":409,"detail":"Cannot activate a completed guard","operation":"<The operation that was attempted, e.g. settled, cancelled, voided>","guardStatus":"<The Guard's current status>","allowedStatuses":"<The statuses in which the operation would have been permitted>","reasons":"<Present instead of allowedStatuses when the rejection is expressed as validation reasons>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/invalid-state-transition"]},"422":{"description":"Request rejected by a business rule\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-settlement/outside-settlement-window`](/problems/guard-settlement/outside-settlement-window/) | Settlement was attempted outside the Guard's permitted settlement (drawdown) window |\n| [`guard-settlement/settlement-exceeds-remaining`](/problems/guard-settlement/settlement-exceeds-remaining/) | The requested settlement amount is greater than the Guard's unsettled balance |\n| [`guard-settlement/funded-request-exceeds-limit`](/problems/guard-settlement/funded-request-exceeds-limit/) | A funded settlement request asks for more than the per-request ceiling for this regulated entity |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"outsideSettlementWindow":{"summary":"Outside Settlement Window","description":"Settle between settlementWindowFrom and settlementWindowTo inclusive. Tell the user when the window opens.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/outside-settlement-window","title":"Outside Settlement Window","status":422,"detail":"Settlement is only permitted within the settlement window (2026-09-01 to 2026-10-01)","settlementWindowFrom":"<First business date on which settlement is permitted>","settlementWindowTo":"<Last business date on which settlement is permitted>","businessDate":"<The business date the request was evaluated against>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"settlementExceedsRemaining":{"summary":"Settlement Exceeds Remaining Amount","description":"Retry with an amount no greater than `unsettled`, or offer to settle the remaining balance in full.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/settlement-exceeds-remaining","title":"Settlement Exceeds Remaining Amount","status":422,"detail":"Settlement amount (50000) exceeds unsettled balance (20000)","requested":"<The settlement amount requested>","unsettled":"<The Guard's remaining unsettled balance>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"fundedRequestExceedsLimit":{"summary":"Funded Request Exceeds Limit","description":"Split the request into smaller ones, or ask CurrencyGuard to raise the ceiling for this regulated entity.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/funded-request-exceeds-limit","title":"Funded Request Exceeds Limit","status":422,"detail":"A funded settlement request may not exceed 250000 GBP (requested: 400000)","requested":"<The total the client would be asked to send, in guard currency>","limit":"<The configured per-request ceiling>","currency":"<The guard currency both figures are in>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-settlement/outside-settlement-window","guard-settlement/settlement-exceeds-remaining","guard-settlement/funded-request-exceeds-limit"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canSettleGuard"]}],"x-entitlement":"regulated.risk-management.canSettleGuard"}},"/api-regulated/v1/guards/{guardId}/settle-guard":{"post":{"tags":["GuardSettlement"],"summary":"Settle a guard","description":"Initiates guard settlement for a regulated entity.\n\n**Required entitlement:** `regulated.risk-management.canSettleGuard`  \n_Entitles the regulated user to settle existing guard positions for their customers_","operationId":"settleGuardRegulated","parameters":[{"name":"guardId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettleGuardRequestDTO"}}},"required":true},"responses":{"201":{"description":"Guard settlement created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardSettlementDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Guard is not in a settleable status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard/invalid-state-transition`](/problems/guard/invalid-state-transition/) | Operation cannot be performed in the current resource state |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"invalidStateTransition":{"summary":"Invalid State Transition","description":"Re-read the Guard and offer only the actions its current status permits. Retrying unchanged will not succeed.","value":{"type":"https://developer.currencyguard.com/problems/guard/invalid-state-transition","title":"Invalid State Transition","status":409,"detail":"Cannot activate a completed guard","operation":"<The operation that was attempted, e.g. settled, cancelled, voided>","guardStatus":"<The Guard's current status>","allowedStatuses":"<The statuses in which the operation would have been permitted>","reasons":"<Present instead of allowedStatuses when the rejection is expressed as validation reasons>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard/invalid-state-transition"]},"422":{"description":"Settlement rejected by a business rule\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`guard-settlement/outside-settlement-window`](/problems/guard-settlement/outside-settlement-window/) | Settlement was attempted outside the Guard's permitted settlement (drawdown) window |\n| [`guard-settlement/settlement-exceeds-remaining`](/problems/guard-settlement/settlement-exceeds-remaining/) | The requested settlement amount is greater than the Guard's unsettled balance |\n| [`guard-settlement/residual-below-minimum`](/problems/guard-settlement/residual-below-minimum/) | The settlement would leave a residual balance below the permitted minimum; settle less, or settle in full |\n| [`guard/sales-margin-exceeded`](/problems/guard/sales-margin-exceeded/) | The sales margin on the request exceeds the maximum permitted for the applicable zone or refund |\n| [`guard-settlement/conversion-rate-crosses-guard-rate`](/problems/guard-settlement/conversion-rate-crosses-guard-rate/) | In the savings zone the conversion rate may not cross the guard rate, which would move the client from savings into protection |\n| [`guard-settlement/client-rate-required`](/problems/guard-settlement/client-rate-required/) | A Guard settlement requires a client conversion amount, so the RE can declare its own margin for this tranche |\n| [`guard-settlement/implied-margin-out-of-band`](/problems/guard-settlement/implied-margin-out-of-band/) | The supplied client conversion amount implies a payment margin outside the permitted band |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"outsideSettlementWindow":{"summary":"Outside Settlement Window","description":"Settle between settlementWindowFrom and settlementWindowTo inclusive. Tell the user when the window opens.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/outside-settlement-window","title":"Outside Settlement Window","status":422,"detail":"Settlement is only permitted within the settlement window (2026-09-01 to 2026-10-01)","settlementWindowFrom":"<First business date on which settlement is permitted>","settlementWindowTo":"<Last business date on which settlement is permitted>","businessDate":"<The business date the request was evaluated against>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"settlementExceedsRemaining":{"summary":"Settlement Exceeds Remaining Amount","description":"Retry with an amount no greater than `unsettled`, or offer to settle the remaining balance in full.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/settlement-exceeds-remaining","title":"Settlement Exceeds Remaining Amount","status":422,"detail":"Settlement amount (50000) exceeds unsettled balance (20000)","requested":"<The settlement amount requested>","unsettled":"<The Guard's remaining unsettled balance>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"residualBelowMinimum":{"summary":"Residual Below Minimum Threshold","description":"Two ways out: settle no more than leaves `minimumResidual`, or settle `settleFullAmount` to close the Guard.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/residual-below-minimum","title":"Residual Below Minimum Threshold","status":422,"detail":"Settlement would leave residual amount below the minimum threshold","residual":"<The residual the requested settlement would leave>","minimumResidual":"<The smallest residual permitted>","thresholdPercent":"<The threshold as a fraction of the original foreign amount>","settleFullAmount":"<The amount that would settle the Guard in full>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"salesMarginExceeded":{"summary":"Sales Margin Exceeded","description":"Reduce the margin to at most `maxMargin` (or `maximumRefund` on a cancellation) and retry.","value":{"type":"https://developer.currencyguard.com/problems/guard/sales-margin-exceeded","title":"Sales Margin Exceeded","status":422,"detail":"Sales margin exceeds maximum permitted margin in protection zone","zone":"<The applicable pricing zone: protection or savings. Absent on a cancellation refund>","salesMargin":"<The sales margin implied by the request>","maxMargin":"<The maximum permitted margin for that zone>","maximumRefund":"<On a cancellation, the maximum refund available>","marketRate":"<The prevailing market rate>","guardRate":"<The Guard's protected rate>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"conversionRateCrossesGuardRate":{"summary":"Conversion Rate Crosses Guard Rate","description":"Use a conversion rate that does not cross `guardRate`. This is a conduct rule and applies even when the margin is within tolerance.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/conversion-rate-crosses-guard-rate","title":"Conversion Rate Crosses Guard Rate","status":422,"detail":"Conversion rate (1.2650) crosses guard rate (1.2700)","conversionRate":"<The conversion rate requested>","guardRate":"<The Guard's protected rate>","marketRate":"<The prevailing market rate>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"clientRateRequired":{"summary":"Client Conversion Amount Required","description":"Retry with `clientConversionAmount` populated.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/client-rate-required","title":"Client Conversion Amount Required","status":422,"detail":"clientConversionAmount is required so the RE can declare its margin for this settlement","requiredField":"<The field that must be supplied>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}},"impliedMarginOutOfBand":{"summary":"Implied Payment Margin Out Of Band","description":"Send an AMOUNT, not a rate. Check the value implies a margin between 0 and `ceiling` against `midConversionAmount`.","value":{"type":"https://developer.currencyguard.com/problems/guard-settlement/implied-margin-out-of-band","title":"Implied Payment Margin Out Of Band","status":422,"detail":"clientConversionAmount implies a payment margin outside the permitted range","clientConversionAmount":"<The amount supplied by the caller>","impliedMargin":"<The payment margin that amount implies>","ceiling":"<The maximum permitted implied margin>","midConversionAmount":"<The mid amount the margin was implied against>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["guard-settlement/outside-settlement-window","guard-settlement/settlement-exceeds-remaining","guard-settlement/residual-below-minimum","guard/sales-margin-exceeded","guard-settlement/conversion-rate-crosses-guard-rate","guard-settlement/client-rate-required","guard-settlement/implied-margin-out-of-band"]},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.risk-management.canSettleGuard"]}],"x-entitlement":"regulated.risk-management.canSettleGuard"}},"/api-regulated/v1/historic-prices/sources":{"get":{"tags":["PriceHistory"],"summary":"Get all available price sources","description":"Retrieves all available subscription source qualifiers for historical price data.","operationId":"getAvailableSourcesRegulated","responses":{"200":{"description":"Available sources retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SourceResponse"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/historic-prices/symbols":{"get":{"tags":["PriceHistory"],"summary":"Get all available symbols for a source","description":"Retrieves all available currency pair symbols for a specific price source.","operationId":"getAvailableSymbolsRegulated","parameters":[{"name":"source","in":"query","description":"Price source","required":false,"schema":{"type":"string","default":"DEFAULT"}}],"responses":{"200":{"description":"Available symbols retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SymbolResponse"}}}}},"400":{"description":"Invalid source — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/historic-prices/{symbol}/prices":{"get":{"tags":["PriceHistory"],"summary":"Get historic FX prices (streaming NDJSON)","description":"Retrieves historical price data for a currency pair over a specified time range as streaming NDJSON. Each line is a JSON object with 'date' and 'price' fields.","operationId":"getHistoricPricesRegulated","parameters":[{"name":"symbol","in":"path","description":"Currency pair symbol (e.g., GBPUSD)","required":true,"schema":{"type":"string"}},{"name":"fromDate","in":"query","description":"Start date for historical data (ISO-8601 date format, e.g., 2024-12-01)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"toDate","in":"query","description":"End date for historical data (ISO-8601 date format, e.g., 2024-12-01)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"source","in":"query","description":"Price source","required":false,"schema":{"type":"string","default":"DEFAULT"}}],"responses":{"200":{"description":"Historical price data streamed successfully","content":{"application/x-ndjson":{"schema":{"type":"array","items":{"type":"string"}}}}},"400":{"description":"Invalid parameters — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - requires sales or internal role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers":{"get":{"tags":["IntroducingBroker"],"summary":"List introducing brokers","description":"Returns all introducing brokers for the authenticated user's regulated entity.","operationId":"getAllRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}}}}},"post":{"tags":["IntroducingBroker"],"summary":"Create introducing broker","description":"Creates an introducing broker under the authenticated user's regulated entity, along with its Cognito user pools. The broker joins the regulated entity's tenant perimeter; giving it one of its own is a separate, deliberate operation.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"createIntroducingBrokerRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTOCreate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"}},"/api-regulated/v1/introducing-brokers/with-full-details":{"get":{"tags":["IntroducingBroker"],"summary":"List introducing brokers with full hierarchy","description":"Returns all IBs with sales users (including PII), companies, customers, and documents in a single response. Designed for full-hierarchy Fuse indexing.","operationId":"getAllWithFullDetailsRegulated","responses":{"200":{"description":"Retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IntroducingBrokerWithFullDetailsDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers/with-sales-users-and-companies":{"get":{"tags":["IntroducingBroker"],"summary":"List introducing brokers with sales users and companies","description":"Returns all introducing brokers for the authenticated user's regulated entity, each with their associated sales users and companies in a single response.","operationId":"getAllWithSalesUsersAndCompaniesRegulated","responses":{"200":{"description":"Retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IntroducingBrokerWithSalesUsersAndCompaniesDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers/{id}":{"get":{"tags":["IntroducingBroker"],"summary":"Get introducing broker by ID","description":"Returns a single introducing broker by ID, scoped to the user's regulated entity.","operationId":"getByIdRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}}}},"put":{"tags":["IntroducingBroker"],"summary":"Update introducing broker","description":"Updates an existing introducing broker, scoped to the user's regulated entity.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"updateIntroducingBrokerRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTOUpdate"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"}},"/api-regulated/v1/introducing-brokers/{id}/logo":{"get":{"tags":["IntroducingBroker"],"summary":"Download introducing broker logo","description":"Download the logo for a specific introducing broker within the authenticated regulated user's regulated entity.","operationId":"downloadIbLogoRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Logo retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or IB not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker or logo not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["IntroducingBroker"],"summary":"Upload introducing broker logo","description":"Upload a logo for a specific introducing broker within the authenticated regulated user's regulated entity. Returns the updated introducing broker.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"uploadIbLogoRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Logo uploaded successfully - returns updated introducing broker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}},"400":{"description":"Invalid file or request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or IB not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"413":{"description":"File too large (max 500KB) — [`http/payload-too-large`](/problems/http/payload-too-large/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"415":{"description":"Invalid file type (must be JPEG, PNG, or WebP) — [`http/unsupported-media-type`](/problems/http/unsupported-media-type/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"},"delete":{"tags":["IntroducingBroker"],"summary":"Delete introducing broker logo","description":"Delete the logo for a specific introducing broker within the authenticated regulated user's regulated entity. Returns the updated introducing broker with logo removed.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"deleteIbLogoRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Logo deleted successfully - returns updated introducing broker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or IB not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"}},"/api-regulated/v1/introducing-brokers/{id}/variables":{"get":{"tags":["IntroducingBroker"],"summary":"Get introducing broker variables","description":"Returns this broker's named variables. Any variable whose name ends in _PASSWORD, _SECRET, _TOKEN or _KEY is flagged secret=true. Its value IS returned here — this endpoint is the one place a credential is served, and clients obscure it until the user reveals it. No other endpoint returns it: the general DTOs have the variables object removed.","operationId":"getIntroducingBrokerVariablesRegulated","parameters":[{"name":"id","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Variables retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"The broker's PII could not be decrypted, so its variables cannot be read — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["IntroducingBroker"],"summary":"Set or replace an introducing broker variable","description":"Upserts one variable by name. Upsert rather than create-or-update because setting a name that already exists is always the operation wanted; there is no separate create.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"setIntroducingBrokerVariableRegulated","parameters":[{"name":"id","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityVariableDTOUpsert"}}},"required":true},"responses":{"200":{"description":"Variable stored; returns the full variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name or value — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"The broker's PII could not be decrypted, so it cannot be edited — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"}},"/api-regulated/v1/introducing-brokers/{id}/variables/{name}":{"delete":{"tags":["IntroducingBroker"],"summary":"Delete an introducing broker variable","description":"Removes one variable by name. A name that is not set is a 404 rather than a silent success, so a misspelled name cannot be mistaken for a credential successfully revoked.\n\n**Required entitlement:** `regulated.parties.canModifyIntroducingBroker`  \n_Entitles the regulated user to create and update introducing broker records within their regulated entity_","operationId":"deleteIntroducingBrokerVariableRegulated","parameters":[{"name":"id","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"name","in":"path","description":"Variable name","required":true,"schema":{"type":"string"},"example":"TRANSFERMATE_USERNAME"}],"responses":{"200":{"description":"Variable removed; returns the remaining variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker or variable not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"The broker's PII could not be decrypted, so it cannot be edited — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyIntroducingBroker"]}],"x-entitlement":"regulated.parties.canModifyIntroducingBroker"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies":{"get":{"tags":["Company"],"summary":"Get all companies for introducing broker","description":"Returns a list of all companies belonging to the specified introducing broker. The authenticated user must have permission to access the specified introducing broker.","operationId":"getAllCompaniesForIntroducingBrokerRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"}],"responses":{"200":{"description":"Companies retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompanyDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to specified introducing broker — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["Company"],"summary":"Create new company","description":"Creates a new company within the authenticated regulated user's regulated entity.\n\n**Required entitlement:** `regulated.parties.canModifyCompany`  \n_Entitles the regulated user to modify company information for their customer accounts_","operationId":"createCompanyForIntroducingBrokerRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTOCreate"}}},"required":true},"responses":{"201":{"description":"Company created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid request data or validation errors — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Conflict - company already exists with same constraints — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Validation errors in request data — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompany"]}],"x-entitlement":"regulated.parties.canModifyCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/with-customers":{"get":{"tags":["Company"],"summary":"Get all companies with customers for introducing broker","description":"Returns a list of all companies belonging to the specified introducing broker, including their associated customers for enhanced search functionality. The authenticated user must have permission to access the specified introducing broker.","operationId":"getAllCompaniesWithCustomersForIntroducingBrokerRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"}],"responses":{"200":{"description":"Companies with customers retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompanyWithCustomersDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to specified introducing broker — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}":{"get":{"tags":["Company"],"summary":"Get company by ID","description":"Retrieves a specific company by its ID, ensuring it belongs to the authenticated regulated user's regulated entity.","operationId":"getCompanyByIdRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Company retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid company ID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["Company"],"summary":"Update company","description":"Updates an existing company within the authenticated regulated user's regulated entity.\n\n**Required entitlement:** `regulated.parties.canModifyCompany`  \n_Entitles the regulated user to modify company information for their customer accounts_","operationId":"updateCompanyInIntroducingBrokerRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Company updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid request data or company ID format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Conflict - company already exists with same constraints — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Validation errors in request data — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompany"]}],"x-entitlement":"regulated.parties.canModifyCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/delete-pii":{"post":{"tags":["CompanyOffboarding"],"summary":"Delete company PII data in regulated entity","description":"Permanently deletes a company's PII data in compliance with GDPR requirements. Company must be DISABLED first. This operation is irreversible and sets status to DELETED. The authenticated user must have permission to access the specified regulated entity.\n\n**Required entitlement:** `regulated.companies.canDeleteCompanyPii`  \n_Entitles the regulated user to permanently delete a company's PII data within their regulated entity_","operationId":"deleteCompanyPiiDataRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Company PII data deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid company ID or regulatedEntityId format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to specified regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"The company is not in a state that permits this operation. Compare `currentStatus` with `requiredStatus` on the problem detail.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.companies.canDeleteCompanyPii"]}],"x-entitlement":"regulated.companies.canDeleteCompanyPii"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/disable":{"post":{"tags":["CompanyOffboarding"],"summary":"Disable company in regulated entity","description":"Disables a company (reversible operation). Only ENABLED companies can be disabled. Disabled companies can later be re-enabled. The authenticated user must have permission to access the specified regulated entity.\n\n**Required entitlement:** `regulated.companies.canDisableCompany`  \n_Entitles the regulated user to disable (suspend) a company within their regulated entity_","operationId":"disableCompanyRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Company disabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid company ID or regulatedEntityId format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to specified regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"The company is not in a state that permits this operation. Compare `currentStatus` with `requiredStatus` on the problem detail.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.companies.canDisableCompany"]}],"x-entitlement":"regulated.companies.canDisableCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/documents":{"get":{"tags":["Company"],"summary":"Get all documents for a company","description":"Returns a list of all documents belonging to the specified company within the authenticated regulated user's regulated entity.","operationId":"getDocumentsForCompanyRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Documents retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/documents/{documentId}/download":{"get":{"tags":["Company"],"summary":"Download a company document","description":"Download the content of a specific document belonging to a company.","operationId":"downloadCompanyDocumentRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"documentId","in":"path","description":"Document ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Document content retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company or document not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/enable":{"post":{"tags":["CompanyOffboarding"],"summary":"Enable company in regulated entity","description":"Enables a previously disabled company (reversible operation). Only DISABLED companies can be enabled. DELETED companies cannot be re-enabled. The authenticated user must have permission to access the specified regulated entity.\n\n**Required entitlement:** `regulated.companies.canEnableCompany`  \n_Entitles the regulated user to re-enable a disabled company within their regulated entity_","operationId":"enableCompanyRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Company enabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid company ID or regulatedEntityId format — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to specified regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"The company is not in a state that permits this operation. Compare `currentStatus` with `requiredStatus` on the problem detail.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.companies.canEnableCompany"]}],"x-entitlement":"regulated.companies.canEnableCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/logo":{"get":{"tags":["Company"],"summary":"Download company logo","description":"Download the company logo for a specific company within the authenticated regulated user's regulated entity.","operationId":"downloadCompanyLogoRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Logo retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company or logo not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["Company"],"summary":"Upload company logo","description":"Upload a logo for a specific company within the authenticated regulated user's regulated entity. Returns the updated company.\n\n**Required entitlement:** `regulated.parties.canModifyCompanyLogo`  \n_Entitles the regulated user to upload and delete company logos for their customer accounts_","operationId":"uploadCompanyLogoRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","description":"Image file to upload (JPEG, PNG, or WebP, max 500KB)","format":"binary"}}}}}},"responses":{"200":{"description":"Logo uploaded successfully - returns updated company","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"400":{"description":"Invalid file or request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"413":{"description":"File too large (max 500KB) — [`http/payload-too-large`](/problems/http/payload-too-large/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"415":{"description":"Invalid file type (must be JPEG, PNG, or WebP) — [`http/unsupported-media-type`](/problems/http/unsupported-media-type/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompanyLogo"]}],"x-entitlement":"regulated.parties.canModifyCompanyLogo"},"delete":{"tags":["Company"],"summary":"Delete company logo","description":"Delete the logo for a specific company within the authenticated regulated user's regulated entity. Returns the updated company with logo removed. Also deletes the physical file from storage and the document record from database.\n\n**Required entitlement:** `regulated.parties.canModifyCompanyLogo`  \n_Entitles the regulated user to upload and delete company logos for their customer accounts_","operationId":"deleteCompanyLogoRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Logo deleted successfully - returns updated company","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompanyLogo"]}],"x-entitlement":"regulated.parties.canModifyCompanyLogo"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/variables":{"get":{"tags":["Company"],"summary":"Get company variables","description":"Returns the company's named variables. Any variable whose name ends in _PASSWORD, _SECRET, _TOKEN or _KEY is flagged secret=true. Its value IS returned here — this endpoint is the one place a credential is served, and clients obscure it until the user reveals it. No other endpoint returns it: the general DTOs have the variables object removed.","operationId":"getCompanyVariablesRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Variables retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["Company"],"summary":"Set or replace a company variable","description":"Upserts one variable by name. Replace rather than create-or-update because a caller setting a name that already exists is always the operation wanted; there is no separate create.\n\n**Required entitlement:** `regulated.parties.canModifyCompany`  \n_Entitles the regulated user to modify company information for their customer accounts_","operationId":"setCompanyVariableRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityVariableDTOUpsert"}}},"required":true},"responses":{"200":{"description":"Variable stored; returns the full variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name or value — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompany"]}],"x-entitlement":"regulated.parties.canModifyCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/companies/{companyId}/variables/{name}":{"delete":{"tags":["Company"],"summary":"Delete a company variable","description":"Removes one variable by name. A name that is not set is a 404 rather than a silent success, so a misspelled name cannot be mistaken for a credential successfully revoked.\n\n**Required entitlement:** `regulated.parties.canModifyCompany`  \n_Entitles the regulated user to modify company information for their customer accounts_","operationId":"deleteCompanyVariableRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-aa55-4001-8000-000000000000"},{"name":"companyId","in":"path","description":"Company ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"name","in":"path","description":"Variable name","required":true,"schema":{"type":"string"},"example":"TRANSFERMATE_PASSWORD"}],"responses":{"200":{"description":"Variable removed; returns the remaining variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or company not in your regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Company or variable not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyCompany"]}],"x-entitlement":"regulated.parties.canModifyCompany"}},"/api-regulated/v1/introducing-brokers/{introducingBrokerId}/sales-users":{"post":{"tags":["SalesUserManagement"],"summary":"Create a new sales user for an introducing broker (CRM-style)","description":"Creates a new sales user for the specified introducing broker. No IDP account, invitation, or email is generated. The introducing broker must belong to the authenticated regulated user's entity.\n\n**Required entitlement:** `regulated.sales-users.canModifySalesUser`  \n_Regulated user can create/update sales users (CRM-style, no invitation)_","operationId":"createSalesUserForIBRegulated","parameters":[{"name":"introducingBrokerId","in":"path","description":"Introducing Broker ID","required":true,"schema":{"type":"string","format":"uuid"},"example":"cccccccc-cc11-4001-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTOCreate"}}},"required":true},"responses":{"201":{"description":"Sales user created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid request body — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role, missing entitlement, or IB belongs to a different regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Introducing broker not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Internal server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.sales-users.canModifySalesUser"]}],"x-entitlement":"regulated.sales-users.canModifySalesUser"}},"/api-regulated/v1/invitation-templates":{"get":{"tags":["InvitationTemplate"],"summary":"Get all invitation templates (non-internal)","description":"Returns invitation email templates for regulated, sales, and customer user types.","operationId":"getAllInvitationTemplatesRegulated","responses":{"200":{"description":"Templates retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InvitationTemplateDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/invitation-templates/{id}":{"get":{"tags":["InvitationTemplate"],"summary":"Get invitation template by ID","description":"Retrieves a specific invitation email template (non-internal only).","operationId":"getInvitationTemplateByIdRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationTemplateDTO"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["InvitationTemplate"],"summary":"Update invitation template","description":"Updates the email message and/or subject for an existing invitation template (non-internal only).\n\n**Required entitlement:** `regulated.templates.canEditEmailTemplate`  \n_Entitles the regulated user to manage invitation email templates for their regulated entity_","operationId":"updateInvitationTemplateRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationTemplateDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Template updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationTemplateDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Template not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.templates.canEditEmailTemplate"]}],"x-entitlement":"regulated.templates.canEditEmailTemplate"}},"/api-regulated/v1/invitations":{"get":{"tags":["Invitation"],"summary":"List invitations","description":"Returns a list of invitations created by the authenticated regulated user. Can be filtered by status, user type, or company.","operationId":"getMyInvitationsRegulated","parameters":[{"name":"status","in":"query","description":"Filter invitations by status","required":false,"schema":{"type":"string"}},{"name":"userType","in":"query","description":"Filter invitations by user type","required":false,"schema":{"type":"string"}},{"name":"company","in":"query","description":"Filter invitations by company ID","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitations retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InvitationDTO"}}}}},"400":{"description":"Invalid parameters — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/invitations/customers":{"post":{"tags":["Invitation"],"summary":"Create customer invitation","description":"Creates an invitation for a new customer user at one of the companies managed by this regulated user.\n\n**Required entitlement:** `regulated.customers.canInviteCustomer`  \n_Entitles the regulated user to invite and onboard customer users_","operationId":"createCustomerInvitationRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerInvitationBySalesUserDTO"}}},"required":true},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - company not managed by this regulated user — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"User already exists or invitation pending — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.customers.canInviteCustomer"]}],"x-entitlement":"regulated.customers.canInviteCustomer"}},"/api-regulated/v1/invitations/regulated":{"post":{"tags":["Invitation"],"summary":"Create regulated user invitation","description":"Creates an invitation for a new regulated user at the same regulated entity. The new regulated user will have access to the same regulated entity as the inviter.\n\n**Required entitlement:** `regulated.users.canInviteRegulatedUser`  \n_Entitles the regulated user to invite and onboard other regulated users within their organization_","operationId":"createRegulatedUserInvitationRegulated","parameters":[{"name":"sendEmail","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRegulatedUserInvitationByRegulatedUserDTO"}}},"required":true},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"User already exists or invitation pending — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.users.canInviteRegulatedUser"]}],"x-entitlement":"regulated.users.canInviteRegulatedUser"}},"/api-regulated/v1/invitations/sales":{"post":{"tags":["Invitation"],"summary":"Create sales user invitation","description":"Creates an invitation for a new sales user at an introducing broker within the regulated user's regulated entity.\n\n**Required entitlement:** `regulated.sales-users.canInviteSalesUser`  \n_Entitles the regulated user to invite and onboard sales users within their regulated entity_","operationId":"createSalesUserInvitationRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSalesUserInvitationByRegulatedUserDTO"}}},"required":true},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - introducing broker not in this regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"User already exists or invitation pending — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.sales-users.canInviteSalesUser"]}],"x-entitlement":"regulated.sales-users.canInviteSalesUser"}},"/api-regulated/v1/invitations/{invitationId}":{"get":{"tags":["Invitation"],"summary":"Get invitation details","description":"Retrieves information for a specific invitation. Regulated users can only access invitations they created.","operationId":"getMyInvitationByIdRegulated","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Invitation retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationDTO"}}}},"400":{"description":"Invalid ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - invitation not owned by user — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Invitation not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/invitations/{invitationId}/complete":{"post":{"tags":["Invitation"],"summary":"Complete invitation if user authenticated","description":"Checks if the invited user has authenticated with the identity provider and completes the invitation if so. This endpoint is typically called by external systems or webhooks when a user completes authentication.","operationId":"completeInvitationRegulated","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Invitation checked and potentially completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationDTO"}}}},"400":{"description":"Invalid ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Invitation not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/invitations/{invitationId}/resend-email":{"post":{"tags":["Invitation"],"summary":"Resend invitation email","description":"Resends the invitation email for a pending, non-expired invitation.\n\n**Required entitlement:** `regulated.invitations.canManageInvitation`  \n_Entitles the regulated user to manage and modify invitations within their scope of responsibility_","operationId":"resendInvitationEmailRegulated","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Email resent successfully"},"400":{"description":"Invitation is not pending, has expired, or invitee type is not eligible — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Invitation not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.invitations.canManageInvitation"]}],"x-entitlement":"regulated.invitations.canManageInvitation"}},"/api-regulated/v1/invitations/{invitationId}/revoke":{"post":{"tags":["Invitation"],"summary":"Revoke invitation","description":"Revokes an invitation created by this regulated user by changing its status to REVOKED.\n\n**Required entitlement:** `regulated.invitations.canManageInvitation`  \n_Entitles the regulated user to manage and modify invitations within their scope of responsibility_","operationId":"revokeMyInvitationRegulated","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Invitation revoked successfully"},"400":{"description":"Invalid ID — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - invitation not owned by user — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Invitation not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"Invalid invitation state for revocation — [`validation/validation-error`](/problems/validation/validation-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.invitations.canManageInvitation"]}],"x-entitlement":"regulated.invitations.canManageInvitation"}},"/api-regulated/v1/market-status":{"get":{"tags":["MarketStatus"],"summary":"Get current market status","description":"Returns current market status including open/closed state, next reopen/close times, and 10-day schedule.","operationId":"getMarketStatusRegulated","responses":{"200":{"description":"Market status retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketStatusDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/payments/funding-accounts":{"get":{"tags":["Payment Rails","Payments"],"summary":"Payable funding accounts for the caller's regulated entity","description":"The payable coordinates a client sends to, for this PSP's own rails only, optionally narrowed to one currency. No balances are returned.","operationId":"listFundingAccountsRegulated","parameters":[{"name":"currency","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The funding accounts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FundingAccountsDTO"}}}},"403":{"description":"Not a PSP caller, or no entity resolvable — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/regulated-entities/self":{"get":{"tags":["RegulatedEntity"],"summary":"Get own regulated entity","description":"Returns the regulated entity details for the authenticated regulated user.","operationId":"getRegulatedEntitySelfRegulated","responses":{"200":{"description":"Regulated entity retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedEntityDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires regulated role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Regulated entity not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["RegulatedEntity"],"summary":"Update regulated entity","description":"Update the regulated entity details for the authenticated regulated user.\n\n**Required entitlement:** `regulated.parties.canModifyRegulatedEntity`  \n_Entitles the regulated user to update their own regulated entity profile_","operationId":"updateRegulatedEntitySelfRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedEntityDTOUpdate"}}},"required":true},"responses":{"200":{"description":"Regulated entity updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulatedEntityDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires regulated role or attempting to update different entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Regulated entity not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Conflict - name already exists or version mismatch — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyRegulatedEntity"]}],"x-entitlement":"regulated.parties.canModifyRegulatedEntity"}},"/api-regulated/v1/regulated-entities/self/logo":{"get":{"tags":["RegulatedEntity"],"summary":"Download logo","description":"Download the logo for the authenticated regulated user's regulated entity. Returns the image file with appropriate content type.","operationId":"downloadSelfLogoRegulated","responses":{"200":{"description":"Logo retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires regulated role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Logo not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["RegulatedEntity"],"summary":"Upload logo","description":"Upload a logo for the authenticated regulated user's regulated entity. Returns the updated regulated entity. Maximum file size is 500KB. Only image files are allowed.\n\n**Required entitlement:** `regulated.parties.canModifyRegulatedEntityLogo`  \n_Entitles the regulated user to upload and delete their own regulated entity logo_","operationId":"uploadSelfLogoRegulated","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Logo uploaded successfully - returns updated regulated entity","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegulatedEntityDTO"}}}},"400":{"description":"Invalid file — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires regulated role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"413":{"description":"File too large - maximum size is 500KB — [`http/payload-too-large`](/problems/http/payload-too-large/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"415":{"description":"Unsupported file type - only images allowed — [`http/unsupported-media-type`](/problems/http/unsupported-media-type/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyRegulatedEntityLogo"]}],"x-entitlement":"regulated.parties.canModifyRegulatedEntityLogo"},"delete":{"tags":["RegulatedEntity"],"summary":"Delete logo","description":"Delete the logo for the authenticated regulated user's regulated entity. Returns the updated regulated entity with logo removed. Also deletes the physical file from storage and the document record from database.\n\n**Required entitlement:** `regulated.parties.canModifyRegulatedEntityLogo`  \n_Entitles the regulated user to upload and delete their own regulated entity logo_","operationId":"deleteSelfLogoRegulated","responses":{"200":{"description":"Logo deleted successfully - returns updated regulated entity","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegulatedEntityDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires regulated role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.parties.canModifyRegulatedEntityLogo"]}],"x-entitlement":"regulated.parties.canModifyRegulatedEntityLogo"}},"/api-regulated/v1/regulated-entities/self/variables":{"get":{"tags":["RegulatedEntity"],"summary":"Get my regulated entity's variables","description":"Returns the entity's named variables. Any variable whose name ends in _PASSWORD, _SECRET, _TOKEN or _KEY is flagged secret=true. Its value IS returned here — this endpoint is the one place a credential is served, and clients obscure it until the user reveals it. No other endpoint returns it: the general DTOs have the variables object removed.","operationId":"getRegulatedEntityVariablesSelfRegulated","responses":{"200":{"description":"Variables retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["RegulatedEntity"],"summary":"Set or replace one of my regulated entity's variables","description":"Upserts one variable by name. Replace rather than create-or-update because a caller setting a name that already exists is always the operation wanted; there is no separate create.","operationId":"setRegulatedEntityVariableSelfRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityVariableDTOUpsert"}}},"required":true},"responses":{"200":{"description":"Variable stored; returns the full variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name or value — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/regulated-entities/self/variables/{name}":{"delete":{"tags":["RegulatedEntity"],"summary":"Delete one of my regulated entity's variables","description":"Removes one variable by name. A name that is not set is a 404 rather than a silent success, so a misspelled name cannot be mistaken for a credential successfully revoked.","operationId":"deleteRegulatedEntityVariableSelfRegulated","parameters":[{"name":"name","in":"path","description":"Variable name","required":true,"schema":{"type":"string"},"example":"TRANSFERMATE_USERNAME"}],"responses":{"200":{"description":"Variable removed; returns the remaining variable list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EntityVariableDTO"}}}}},"400":{"description":"Invalid variable name — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Variable not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/reports/hedge-coverage":{"get":{"tags":["Reports"],"summary":"Hedge coverage report","description":"Per currency pair: sum of guard intrinsic value in the protection zone (and settlement window), the corresponding back-to-back option mid MtM, and the resulting coverage ratios. Scoped to the authenticated regulated entity.","operationId":"getHedgeCoverageReportRegulated","responses":{"200":{"description":"Report computed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HedgeCoverageReportDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/server-time":{"get":{"tags":["ServerTime"],"summary":"Get server time","description":"Returns the current server time used for synchronising the UI application clock with the server. In lower test environments the server clock may be back dated and the mode may be SIMULATED rather than REAL. The response includes the current timestamp and clock mode (REAL/SIMULATED). This endpoint is accessible to all authenticated users.","operationId":"getServerTimeRegulated","responses":{"200":{"description":"Server time retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClockSnapshotDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/subscription-messages/clock-message":{"post":{"tags":["SubscriptionMessages"],"summary":"Clock Message Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageEnvelope<ClockSnapshotDTO> type for system clock synchronization.\n\nSubscription Keys:\n- Clock: { \"message_type\": \"CLOCK\", \"frequency\": 1000.0 }\n- Date Roll: { \"message_type\": \"CLOCK_DATE_ROLL\" }\n","operationId":"clockMessageTypeRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeClockSnapshotDTO"}}}}}}},"/api-regulated/v1/subscription-messages/fx-price-message":{"post":{"tags":["SubscriptionMessages"],"summary":"FX Price Message Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageEnvelope<FXPriceDTO> type for FX price data.\n\nSubscription Key: { \"message_type\": \"FX_PRICE\", \"symbol\": \"GBPUSD\", \"source\": \"DEFAULT\" }\n","operationId":"fxPriceMessageTypeRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeFXPriceDTO"}}}}}}},"/api-regulated/v1/subscription-messages/fx-price-state-message":{"post":{"tags":["SubscriptionMessages"],"summary":"FX Price State Message Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageEnvelope<FXPriceStateDTO> type for real-time FX price updates.\n\nSubscription Key: { \"message_type\": \"FX_PRICE\", \"symbol\": \"GBPUSD\", \"source\": \"DEFAULT\" }\n","operationId":"fxPriceStateMessageTypeRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeFXPriceStateDTO"}}}}}}},"/api-regulated/v1/subscription-messages/guard-message":{"post":{"tags":["SubscriptionMessages"],"summary":"Guard Message Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageEnvelope<GuardDTO> type for guard lifecycle notifications.\nUses the redacted GuardDTO (not GuardDTOInternal) — internal fields are excluded.\n\nSubscription Keys:\n- All Guards: { \"message_type\": \"GUARDS\" }\n\n","operationId":"guardMessageTypeRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeGuardDTO"}}}}}}},"/api-regulated/v1/subscription-messages/market-status-message":{"post":{"tags":["SubscriptionMessages"],"summary":"Market Status Message Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageEnvelope<MarketStatusDTO> type for market open/close status updates.\nProvides real-time market status including current state, next open/close times,\nand upcoming schedule.\n\nSubscription Key: { \"messageType\": \"MARKET_STATUS\" }\n","operationId":"marketStatusMessageTypeRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeMarketStatusDTO"}}}}}}},"/api-regulated/v1/subscription-messages/message-envelope":{"post":{"tags":["SubscriptionMessages"],"summary":"Message Envelope Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the generic MessageEnvelope<T> type used to wrap all SSE messages.\nEvery SSE data event follows this structure:\n\n{\n    \"header\": {\n        \"subscription_key\": { ... },\n        \"timestamp\": \"2025-01-29T10:22:06Z\"\n    },\n    \"body\": { ... }\n}\n","operationId":"getMessageEnvelopeTypeRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeObject"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageEnvelopeObject"}}}}}}},"/api-regulated/v1/subscription-messages/message-header":{"post":{"tags":["SubscriptionMessages"],"summary":"Message Header Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageHeader type included in all message envelopes.\n","operationId":"messageHeaderTypeRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageHeader"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageHeader"}}}}}}},"/api-regulated/v1/subscription-messages/message-types":{"get":{"tags":["SubscriptionMessages"],"summary":"Message Type Enum","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the MessageType enum used in subscription keys.\n","operationId":"getMessageTypesRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"type":"string","enum":["FX_PRICE","MARKET_DATA","GUARDS","FX_OPTIONS","GUARD_PRICE","GUARD_PERFORMANCE","CLOCK","CLOCK_DATE_ROLL","GUARD_QUOTES","FX_VOL_SURFACE","ZERO_RATE_CURVE","PORTFOLIO_VALUATIONS","PORTFOLIO_RISK","FX_FORWARD_CURVE","FX_POSITION_PNL_VALUATION","MARKET_STATUS"]}}}}}}}},"/api-regulated/v1/subscription-messages/subscription-actions":{"get":{"tags":["SubscriptionMessages"],"summary":"Subscription Action Enum","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the SubscriptionAction enum for subscribe/unsubscribe operations.\n","operationId":"getSubscriptionActionsRegulated","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"type":"string","enum":["SUBSCRIBE","UNSUBSCRIBE"]}}}}}}}},"/api-regulated/v1/subscription-messages/subscription-key":{"post":{"tags":["SubscriptionMessages"],"summary":"Subscription Key Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the SubscriptionKey type used to identify and route message streams.\n","operationId":"subscriptionKeyTypeRegulated","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionKeyCLOCK"},{"$ref":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL"},{"$ref":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_OPTIONS"},{"$ref":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION"},{"$ref":"#/components/schemas/SubscriptionKeyFX_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARDS"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_QUOTES"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_DATA"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_STATUS"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS"},{"$ref":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE"}]}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionKeyCLOCK"},{"$ref":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL"},{"$ref":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_OPTIONS"},{"$ref":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION"},{"$ref":"#/components/schemas/SubscriptionKeyFX_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARDS"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_QUOTES"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_DATA"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_STATUS"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS"},{"$ref":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE"}]}}}}}}},"/api-regulated/v1/subscription-messages/subscription-request":{"post":{"tags":["SubscriptionMessages"],"summary":"Subscription Request Type","description":"SYNTHETIC ENDPOINT - DO NOT CALL!\n\nExposes the SubscriptionRequest type used by clients to subscribe/unsubscribe from data streams.\n","operationId":"subscriptionRequestTypeRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SubscriptionRequest"}}}}}}},"/api-regulated/v1/trades/export":{"get":{"tags":["TradeExport"],"summary":"Export trades","description":"Downloads Guards and Guard Settlements scoped to the authenticated regulated entity. FX options (CGL's back-to-back bank hedges) and cash trades are excluded. Internal economics (guard margin etc.) are redacted via the regulated DTO variant. Entities are exported by UUID. Supports CSV (default) and Parquet output formats.","operationId":"exportTradesRegulated","parameters":[{"name":"guardId","in":"query","description":"Guard ID — if provided, exports the full guard chain (all extensions, settlements)","required":false,"schema":{"type":"string"}},{"name":"currencyPair","in":"query","description":"Currency pair filter, e.g. GBPUSD or GBP/USD","required":false,"schema":{"type":"string"}},{"name":"entityType","in":"query","description":"Entity type filter, e.g. Guard, GuardSettlement","required":false,"schema":{"type":"string"}},{"name":"fromDate","in":"query","description":"Include trades with tradeDate >= fromDate (ISO8601, e.g. 2026-03-01T00:00:00Z)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"toDate","in":"query","description":"Include trades with tradeDate <= toDate (ISO8601, e.g. 2026-03-04T23:59:59Z)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"format","in":"query","description":"Output format: csv (default) or parquet","required":false,"schema":{"type":"string","default":"csv"}}],"responses":{"200":{"description":"File download","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Guard not found (when guardId specified) — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/trading-calendars/{symbol}/resolve-tenor":{"get":{"tags":["TradingCalendar"],"summary":"Resolve tenor or date to business date","description":"Resolves a tenor symbol or ISO date to an actual business date using the specified trading calendar. Supports standard tenors (TOD, ON, 1M, etc.) and broken dates (YYYY-MM-DD). Returns the resolved date with adjustment information if the date required adjustment to a business day.","operationId":"resolveSingleTenorRegulated","parameters":[{"name":"symbol","in":"path","description":"Calendar symbol (GBPUSD for FX settlement, GBP for domestic, USNY for financial center)","required":true,"schema":{"type":"string"}},{"name":"tenor","in":"query","description":"Tenor symbol or ISO date to resolve (e.g., TOD, ON, 1M, 3M, 1Y, 2025-12-25)","required":true,"schema":{"type":"string"}},{"name":"referenceDate","in":"query","description":"Reference date in YYYY-MM-DD format (optional, defaults to current date)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tenor or date resolved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenorDateMapping"}}}},"400":{"description":"Invalid request parameters — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Calendar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/trading-calendars/{symbol}/resolve-tenors":{"get":{"tags":["TradingCalendar"],"summary":"Resolve multiple tenors to business dates","description":"Resolves a list of tenor symbols to actual business dates using the specified trading calendar. Returns resolved dates with adjustment information for each tenor.","operationId":"resolveTenorsRegulated","parameters":[{"name":"symbol","in":"path","description":"Calendar symbol (GBPUSD for FX settlement, GBP for domestic, USNY for financial center)","required":true,"schema":{"type":"string"}},{"name":"tenor","in":"query","description":"Tenor symbols or ISO dates to resolve (e.g., TOD, ON, 1M, 3M, 1Y, 2025-12-25). Repeat for multiple.","required":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"referenceDate","in":"query","description":"Reference date in YYYY-MM-DD format (optional, defaults to current date)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tenors resolved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenorResolutionResponseDTO"}}}},"400":{"description":"Invalid request parameters — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Calendar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/trading-calendars/{symbol}/snapshot":{"get":{"tags":["TradingCalendar"],"summary":"Get trading calendar snapshot","description":"Returns the current trading calendar for a symbol including business day rules and holidays. Supports GBPUSD (FX settlement), GBP (domestic), USNY (financial center) and other calendar symbols.","operationId":"getTradingCalendarSnapshotRegulated","parameters":[{"name":"symbol","in":"path","description":"Calendar symbol (GBPUSD for FX settlement, GBP for domestic, USNY for financial center)","required":true,"schema":{"type":"string"}},{"name":"year","in":"query","description":"Year for calendar display","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"month","in":"query","description":"Month (1-12)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"fromDate","in":"query","description":"Start date (YYYY-MM-DD)","required":false,"schema":{"type":"string"}},{"name":"toDate","in":"query","description":"End date (YYYY-MM-DD)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trading calendar retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingCalendarDTO"}}}},"404":{"description":"Calendar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/trading-configs":{"get":{"tags":["Configuration"],"summary":"Get trading configurations","description":"Retrieves name-value configuration settings for the trading domain. Note: This endpoint may be deprecated in a future release.","operationId":"getAllTradingConfigurationsRegulated","responses":{"200":{"description":"Configurations retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TradingConfigurationDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - insufficient privileges — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/trading-configs/{key}":{"get":{"tags":["Configuration"],"summary":"Get trading configuration by key","description":"Retrieves a specific configuration value by its key. Note: This endpoint may be deprecated in a future release.","operationId":"getTradingConfigurationByKeyRegulated","parameters":[{"name":"key","in":"path","description":"Configuration key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Configuration retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingConfigurationDTO"}}}},"400":{"description":"Invalid configuration key — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Access denied - insufficient privileges — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Configuration not found or not accessible — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users":{"get":{"tags":["User"],"summary":"Get all users","description":"Returns a list of all users (sales + customers) within the regulated entity. Regulated users can only see users within their own regulated entity.","operationId":"getAllUsersInRegulatedEntityRegulated","responses":{"200":{"description":"Users retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/by-sub-claim/{subClaim}":{"get":{"tags":["User"],"summary":"Get user by sub claim","description":"Returns a specific user by their JWT sub claim if they exist within the regulated entity. Regulated users can only access users within their own regulated entity.","operationId":"getUserBySubClaimInRegulatedEntityRegulated","parameters":[{"name":"subClaim","in":"path","description":"Sub Claim from JWT token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid subClaim — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found in regulated entity — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/full-profile":{"get":{"tags":["User"],"summary":"Get all users with full profile","description":"Returns all users (regulated + sales + customers) within the token holder's regulated entity, with complete role-specific contexts.","operationId":"getAllUsersWithFullProfileRegulated","responses":{"200":{"description":"Users retrieved successfully","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserFullProfileDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/self":{"get":{"tags":["User"],"summary":"Get user profile","description":"Returns comprehensive user information including all role-specific contexts in a single response. Reduces the need for multiple API calls during session initialization.","operationId":"getUserSelfRegulated","responses":{"200":{"description":"Complete user profile retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserFullProfileDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User record not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"put":{"tags":["User"],"summary":"Update own details","description":"Update PII details for the authenticated regulated user (name, location, phone, job title). Entitlements are not affected.\n\n**Required entitlement:** `regulated.my-profile.canModifyMyUserDetails`  \n_Entitles the regulated user to update their own profile details_","operationId":"updateUserSelfRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTOUpdate"}}},"required":true},"responses":{"200":{"description":"User updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.my-profile.canModifyMyUserDetails"]}],"x-entitlement":"regulated.my-profile.canModifyMyUserDetails"}},"/api-regulated/v1/users/self/avatar":{"get":{"tags":["User"],"summary":"Download avatar","description":"Download the avatar for the authenticated user. Returns the image file with appropriate content type.","operationId":"downloadSelfAvatarRegulated","responses":{"200":{"description":"Avatar retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User record not found — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Avatar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"post":{"tags":["User"],"summary":"Upload avatar","description":"Upload an avatar for the authenticated user. Returns the updated user. Maximum file size is 500KB. The system will automatically determine user type and store the document appropriately.\n\n**Required entitlement:** `regulated.my-profile.canModifyMyAvatar`  \n_Entitles the regulated user to upload and delete their own avatar_","operationId":"uploadSelfAvatarRegulated","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Avatar uploaded successfully - returns updated user","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid file — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User record not found — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"413":{"description":"File too large - maximum size is 500KB — [`http/payload-too-large`](/problems/http/payload-too-large/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"415":{"description":"Unsupported file type - only images allowed — [`http/unsupported-media-type`](/problems/http/unsupported-media-type/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.my-profile.canModifyMyAvatar"]}],"x-entitlement":"regulated.my-profile.canModifyMyAvatar"},"delete":{"tags":["User"],"summary":"Delete avatar","description":"Delete the avatar for the authenticated user. Returns the updated user with avatar removed. Also deletes the physical file from storage and the document record from database.\n\n**Required entitlement:** `regulated.my-profile.canModifyMyAvatar`  \n_Entitles the regulated user to upload and delete their own avatar_","operationId":"deleteSelfAvatarRegulated","responses":{"200":{"description":"Avatar deleted successfully - returns updated user","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User record not found — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.my-profile.canModifyMyAvatar"]}],"x-entitlement":"regulated.my-profile.canModifyMyAvatar"}},"/api-regulated/v1/users/self/entitlements":{"put":{"tags":["User"],"summary":"Update own entitlements","description":"Update the entitlements for the authenticated regulated user. PII data is not affected.\n\n**Required entitlement:** `regulated.my-profile.canEditOwnEntitlement`  \n_Entitles the regulated user to update their own entitlements_","operationId":"updateSelfEntitlementsRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonNode"}}},"required":true},"responses":{"200":{"description":"Entitlements updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid request data — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.my-profile.canEditOwnEntitlement"]}],"x-entitlement":"regulated.my-profile.canEditOwnEntitlement"}},"/api-regulated/v1/users/self/preferences":{"get":{"tags":["User"],"summary":"Get own UI preferences","description":"Returns the authenticated user's UI preferences, namespaced by section. Returns an empty object for a user who has never saved any.","operationId":"getUserPreferencesSelfRegulated","responses":{"200":{"description":"Preferences retrieved","content":{"*/*":{"schema":{"$ref":"#/components/schemas/JsonNode"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/self/preferences/{section}":{"put":{"tags":["User"],"summary":"Replace one section of own UI preferences","description":"Replaces a single named section, leaving the others untouched, so two pages or two browser tabs can each save what they own without discarding the other's work. Returns the full preferences after the write.","operationId":"updateUserPreferencesSectionSelfRegulated","parameters":[{"name":"section","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonNode"}}},"required":true},"responses":{"200":{"description":"Preferences updated","content":{"*/*":{"schema":{"$ref":"#/components/schemas/JsonNode"}}}},"400":{"description":"Section name missing or blank — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User record not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/{userId}":{"get":{"tags":["User"],"summary":"Get user by ID","description":"Returns a specific user by their UUID if they exist within the regulated entity. Regulated users can only access users within their own regulated entity.","operationId":"getUserByIdInRegulatedEntityRegulated","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"400":{"description":"Invalid userId — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found in regulated entity — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/{userId}/avatar":{"get":{"tags":["User"],"summary":"Download avatar","description":"Download the avatar for any user (sales, internal, or customer) within the regulated entity. Regulated users can only access avatars of users within their regulated entity scope.","operationId":"downloadUserAvatarRegulated","parameters":[{"name":"userId","in":"path","description":"User ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Avatar retrieved successfully","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized - requires REGULATED role or no access to regulated entity — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User or avatar not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api-regulated/v1/users/{userId}/delete-pii-customer":{"post":{"tags":["Offboarding"],"summary":"Delete customer PII data","description":"Permanently deletes PII data for a customer user (GDPR-compliant). User must be DISABLED first.\n\n**Required entitlement:** `regulated.customers.canDeleteCustomerPii`  \n_Entitles the regulated user to permanently delete a customer user's PII data within their regulated entity_","operationId":"deletePiiCustomerRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PII data deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not disabled first or already deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.customers.canDeleteCustomerPii"]}],"x-entitlement":"regulated.customers.canDeleteCustomerPii"}},"/api-regulated/v1/users/{userId}/delete-pii-regulated":{"post":{"tags":["Offboarding"],"summary":"Delete regulated user PII data","description":"Permanently deletes PII data for a regulated user (GDPR-compliant). User must be DISABLED first.\n\n**Required entitlement:** `regulated.users.canDeleteRegulatedUserPii`  \n_Entitles the regulated user to permanently delete a regulated user's PII data within their regulated entity_","operationId":"deletePiiRegulatedUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PII data deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not disabled first or already deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canDeleteRegulatedUserPii"]}],"x-entitlement":"regulated.users.canDeleteRegulatedUserPii"}},"/api-regulated/v1/users/{userId}/delete-pii-sales-user":{"post":{"tags":["Offboarding"],"summary":"Delete sales user PII data","description":"Permanently deletes PII data for a sales user (GDPR-compliant). User must be DISABLED first.\n\n**Required entitlement:** `regulated.sales-users.canDeleteSalesUserPii`  \n_Entitles the regulated user to permanently delete a sales user's PII data within their regulated entity_","operationId":"deletePiiSalesUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PII data deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not disabled first or already deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.sales-users.canDeleteSalesUserPii"]}],"x-entitlement":"regulated.sales-users.canDeleteSalesUserPii"}},"/api-regulated/v1/users/{userId}/disable-customer":{"post":{"tags":["Offboarding"],"summary":"Disable a customer user","description":"Disables a customer user by their userId (reversible operation). Customer must be in a company within the actor's regulated entity.\n\n**Required entitlement:** `regulated.customers.canDisableCustomer`  \n_Entitles the regulated user to disable (suspend) customer users within their regulated entity_","operationId":"disableCustomerRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User disabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is already disabled or deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.customers.canDisableCustomer"]}],"x-entitlement":"regulated.customers.canDisableCustomer"}},"/api-regulated/v1/users/{userId}/disable-regulated":{"post":{"tags":["Offboarding"],"summary":"Disable a regulated user","description":"Disables a regulated user by their userId (reversible operation). Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.users.canDisableRegulatedUser`  \n_Entitles the regulated user to disable (suspend) other regulated users within their regulated entity_","operationId":"disableRegulatedUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User disabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is already disabled or deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canDisableRegulatedUser"]}],"x-entitlement":"regulated.users.canDisableRegulatedUser"}},"/api-regulated/v1/users/{userId}/disable-sales-user":{"post":{"tags":["Offboarding"],"summary":"Disable a sales user","description":"Disables a sales user by their userId (reversible operation). Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.sales-users.canDisableSalesUser`  \n_Entitles the regulated user to disable (suspend) sales users within their regulated entity_","operationId":"disableSalesUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User disabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is already disabled or deleted\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.sales-users.canDisableSalesUser"]}],"x-entitlement":"regulated.sales-users.canDisableSalesUser"}},"/api-regulated/v1/users/{userId}/enable-customer":{"post":{"tags":["Offboarding"],"summary":"Enable a customer user","description":"Enables a customer user (reversible operation). Customer must be in a company within the actor's regulated entity.\n\n**Required entitlement:** `regulated.customers.canEnableCustomer`  \n_Entitles the regulated user to re-enable a disabled customer user within their regulated entity_","operationId":"enableCustomerRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User enabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in DISABLED or PENDING status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.customers.canEnableCustomer"]}],"x-entitlement":"regulated.customers.canEnableCustomer"}},"/api-regulated/v1/users/{userId}/enable-regulated":{"post":{"tags":["Offboarding"],"summary":"Enable a regulated user","description":"Enables a regulated user (reversible operation). Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.users.canEnableRegulatedUser`  \n_Entitles the regulated user to re-enable a disabled regulated user within their regulated entity_","operationId":"enableRegulatedUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User enabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in DISABLED or PENDING status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canEnableRegulatedUser"]}],"x-entitlement":"regulated.users.canEnableRegulatedUser"}},"/api-regulated/v1/users/{userId}/enable-sales-user":{"post":{"tags":["Offboarding"],"summary":"Enable a sales user","description":"Enables a sales user (reversible operation). Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.sales-users.canEnableSalesUser`  \n_Entitles the regulated user to re-enable a disabled sales user within their regulated entity_","operationId":"enableSalesUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User enabled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in DISABLED or PENDING status\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.sales-users.canEnableSalesUser"]}],"x-entitlement":"regulated.sales-users.canEnableSalesUser"}},"/api-regulated/v1/users/{userId}/reset-mfa-customer":{"post":{"tags":["Offboarding"],"summary":"Reset MFA for a customer user","description":"Resets MFA (TOTP) for a customer user, forcing re-enrollment on next login. Customer must be in a company within the actor's regulated entity.\n\n**Required entitlement:** `regulated.users.canResetUserMfa`  \n_Entitles the regulated user to reset MFA (TOTP) for users within their regulated entity_","operationId":"resetMfaCustomerRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"MFA reset successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in ENABLED status or has no Cognito account\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canResetUserMfa"]}],"x-entitlement":"regulated.users.canResetUserMfa"}},"/api-regulated/v1/users/{userId}/reset-mfa-regulated":{"post":{"tags":["Offboarding"],"summary":"Reset MFA for a regulated user","description":"Resets MFA (TOTP) for a regulated user, forcing re-enrollment on next login. Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.users.canResetUserMfa`  \n_Entitles the regulated user to reset MFA (TOTP) for users within their regulated entity_","operationId":"resetMfaRegulatedUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"MFA reset successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in ENABLED status or has no Cognito account\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canResetUserMfa"]}],"x-entitlement":"regulated.users.canResetUserMfa"}},"/api-regulated/v1/users/{userId}/reset-mfa-sales-user":{"post":{"tags":["Offboarding"],"summary":"Reset MFA for a sales user","description":"Resets MFA (TOTP) for a sales user, forcing re-enrollment on next login. Target must be in the same regulated entity.\n\n**Required entitlement:** `regulated.users.canResetUserMfa`  \n_Entitles the regulated user to reset MFA (TOTP) for users within their regulated entity_","operationId":"resetMfaSalesUserRegulated","parameters":[{"name":"userId","in":"path","description":"The target user's ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"MFA reset successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDTO"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"User not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"User is not in ENABLED status or has no Cognito account\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`onboarding/entity-lifecycle-state-invalid`](/problems/onboarding/entity-lifecycle-state-invalid/) | The user or company is not in a state that permits the requested operation |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"entityLifecycleStateInvalid":{"summary":"Entity Lifecycle State Invalid","description":"Compare `currentStatus` with `requiredStatus`. Move the entity into the required state first, or hide the action while it is not available.","value":{"type":"https://developer.currencyguard.com/problems/onboarding/entity-lifecycle-state-invalid","title":"Entity Lifecycle State Invalid","status":422,"detail":"User must be DISABLED before PII can be deleted. Current status: ENABLED","entityType":"<What the operation was attempted on, e.g. user or company>","currentStatus":"<The state the entity is in now>","requiredStatus":"<The state the operation needs, where a single one applies>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["onboarding/entity-lifecycle-state-invalid"]}},"security":[{"entitlementsScheme":["regulated.users.canResetUserMfa"]}],"x-entitlement":"regulated.users.canResetUserMfa"}},"/api-regulated/v1/webhook-subscriptions":{"get":{"tags":["Webhooks"],"summary":"List webhook subscriptions","description":"Returns all subscriptions for the authenticated regulated entity, with delivery health fields.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"listRegulated","responses":{"200":{"description":"Subscriptions retrieved","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookSubscriptionDTO"}}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"},"post":{"tags":["Webhooks"],"summary":"Register a webhook subscription","description":"Creates a subscription and returns the one-time signing secret.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"createWebhookSubscriptionRegulated","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionCreateRequestDTO"}}},"required":true},"responses":{"201":{"description":"Subscription created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionCreatedDTO"}}}},"400":{"description":"Invalid request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Subscription name already in use — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"}},"/api-regulated/v1/webhook-subscriptions/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook subscription","description":"Returns one subscription owned by the authenticated regulated entity, including delivery status.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"getRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Subscription retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Subscription not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook subscription","description":"Soft-deletes the subscription. Delivery stops immediately.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"deleteRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Subscription deleted"},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Subscription not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"},"patch":{"tags":["Webhooks"],"summary":"Update a webhook subscription","description":"Updates endpoint URL and/or status. Setting status to ACTIVE resumes a paused subscription from its checkpoint.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"updateWebhookSubscriptionRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionUpdateRequestDTO"}}},"required":true},"responses":{"200":{"description":"Subscription updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionDTO"}}}},"400":{"description":"Invalid request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Subscription not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"}},"/api-regulated/v1/webhook-subscriptions/{id}/replay":{"post":{"tags":["Webhooks"],"summary":"Replay webhook events","description":"Rewinds the delivery checkpoint so the dispatcher re-delivers historical events on its next poll. Omit fromSequence to replay from the beginning. Resumes the subscription if paused.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"replayRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionReplayRequestDTO"}}}},"responses":{"200":{"description":"Replay armed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionDTO"}}}},"400":{"description":"Invalid request — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Subscription not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"}},"/api-regulated/v1/webhook-subscriptions/{id}/rotate-secret":{"post":{"tags":["Webhooks"],"summary":"Rotate the signing secret","description":"Generates a new signing secret and returns it once. The previous secret stops being valid immediately.\n\n**Required entitlement:** `regulated.api-clients.canManageWebhooks`  \n_Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery_","operationId":"rotateSecretRegulated","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Secret rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSubscriptionCreatedDTO"}}}},"401":{"description":"Not authenticated — [`security/authentication-failed`](/problems/security/authentication-failed/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"Not authorized — [`security/insufficient-permissions`](/problems/security/insufficient-permissions/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"Subscription not found — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}},"security":[{"entitlementsScheme":["regulated.api-clients.canManageWebhooks"]}],"x-entitlement":"regulated.api-clients.canManageWebhooks"}},"/api/v1/auth/pool-config":{"get":{"tags":["AuthPoolConfig"],"summary":"Look up Cognito pool config by email domain","description":"Returns pool configuration for the given email domain. Always returns 200 OK — unknown domains receive a valid pool to prevent domain enumeration. Pass app=dev-portal to receive the developer portal app client ID instead of the default.","operationId":"getPoolConfig","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"}},{"name":"poolType","in":"query","required":false,"schema":{"type":"string"}},{"name":"app","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolConfigResponseDTO"}}}}}}},"/api/v1/config/ui":{"get":{"tags":["UIConfig"],"summary":"Runtime UI configuration","description":"Returns environment-specific configuration for frontend apps. Public, unauthenticated. All values are derived from server SSM/YAML properties.","operationId":"getUiConfig","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UiConfigResponseDTO"}}}}}}},"/api/v1/guard-pricing/chat":{"post":{"tags":["GuardPricing"],"summary":"AI chat with Guard pricing tools — send conversation messages, receive AI response with live pricing data","operationId":"chat","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpGuardChatRequestDTO"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpGuardChatResponseDTO"}}}}}}},"/api/v1/guard-pricing/currencies":{"get":{"tags":["GuardPricing"],"summary":"List supported currency pairs","operationId":"getSupportedCurrencies","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}}}},"/api/v1/guard-pricing/extension-quote":{"get":{"tags":["GuardPricing"],"summary":"Get an indicative guard extension price quote","operationId":"getExtensionQuote","parameters":[{"name":"guardCurrency","in":"query","required":true,"schema":{"type":"string"}},{"name":"foreignCurrency","in":"query","required":true,"schema":{"type":"string"}},{"name":"payReceive","in":"query","required":true,"schema":{"type":"string"}},{"name":"foreignAmount","in":"query","required":true,"schema":{"type":"number"}},{"name":"originalSettlementDate","in":"query","required":true,"schema":{"type":"string"}},{"name":"extendedSettlementDate","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpGuardExtensionQuoteDTO"}}}}}}},"/api/v1/guard-pricing/forward-rate":{"get":{"tags":["GuardPricing"],"summary":"Get forward FX rate for a currency pair and tenor","operationId":"getForwardRate","parameters":[{"name":"base","in":"query","required":true,"schema":{"type":"string"}},{"name":"quote","in":"query","required":true,"schema":{"type":"string"}},{"name":"tenor","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpForwardRateDTO"}}}}}}},"/api/v1/guard-pricing/product-info":{"get":{"tags":["GuardPricing"],"summary":"Get Guard product information","operationId":"getProductInfo","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/api/v1/guard-pricing/quote":{"get":{"tags":["GuardPricing"],"summary":"Get an indicative guard price quote","operationId":"getQuote","parameters":[{"name":"guardCurrency","in":"query","required":true,"schema":{"type":"string"}},{"name":"foreignCurrency","in":"query","required":true,"schema":{"type":"string"}},{"name":"payReceive","in":"query","required":true,"schema":{"type":"string"}},{"name":"foreignAmount","in":"query","required":true,"schema":{"type":"number"}},{"name":"settlementDate","in":"query","required":true,"schema":{"type":"string"}},{"name":"guardRate","in":"query","required":false,"schema":{"type":"number"}},{"name":"payLater","in":"query","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpGuardQuoteDTO"}}}}}}},"/api/v1/guard-pricing/settlement-date":{"get":{"tags":["GuardPricing"],"summary":"Resolve a tenor to a valid business settlement date for a currency pair","operationId":"resolveSettlementDate","parameters":[{"name":"currencyPair","in":"query","required":true,"schema":{"type":"string"}},{"name":"tenor","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/guard-pricing/spot-rate":{"get":{"tags":["GuardPricing"],"summary":"Get spot FX rate for a currency pair","operationId":"getSpotRate","parameters":[{"name":"base","in":"query","required":true,"schema":{"type":"string"}},{"name":"quote","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpSpotRateDTO"}}}}}}},"/api/v1/invitations/accept":{"post":{"tags":["Invitation"],"summary":"Accept invitation","description":"Public endpoint for any user to accept their invitation. No authentication required. The invitation token (from the email link) identifies the user. Password is optional: when provided (seed scripts), the backend sets it directly; when omitted (browser flow), the user sets their password on first login via Cognito challenge.","operationId":"acceptInvitation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInvitationRequestDTO"}}},"required":true},"responses":{"200":{"description":"Invitation accepted successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AcceptInvitationResponseDTO"}}}},"400":{"description":"Invalid or expired token — [`http/malformed-request`](/problems/http/malformed-request/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Invitation already accepted — [`http/resource-conflict`](/problems/http/resource-conflict/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"422":{"description":"The supplied password does not meet the password policy. The `rule` member names which rule was broken and the limit it is measured against travels alongside it.\n\n**Problem types returned by this endpoint**\n\n| Type | Meaning |\n|---|---|\n| [`validation/password-policy-not-met`](/problems/validation/password-policy-not-met/) | The supplied password does not meet the password policy |\n","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"},"examples":{"passwordPolicyNotMet":{"summary":"Password Policy Not Met","description":"Choose a password that satisfies the rule named in the `rule` member and retry. The limit it is measured against is carried alongside it.","value":{"type":"https://developer.currencyguard.com/problems/validation/password-policy-not-met","title":"Password Policy Not Met","status":422,"detail":"Password must be at least 8 characters long","rule":"<Which rule was broken: empty, too-short, too-long or insufficient-complexity>","minimumLength":"<The shortest password accepted>","maximumLength":"<The longest password accepted>","requiredCharacterClasses":"<How many of lowercase, uppercase, digit and symbol must appear (all four)>","correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"}}}}},"x-problem-types":["validation/password-policy-not-met"]},"429":{"description":"Too many requests - rate limit exceeded — [`security/rate-limit-exceeded`](/problems/security/rate-limit-exceeded/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/v1/problem-types":{"get":{"tags":["ProblemTypes"],"summary":"Get all RFC 9457 problem types","description":"Returns the complete registry of RFC 9457 problem types with environment-specific URIs. The response includes all problem types organized by name and category, along with metadata about each type including URI, title, description, HTTP status code, and usage examples. URIs are dynamically generated for the current environment (local, UAT, production). This endpoint is publicly accessible and does not require authentication.","operationId":"getAllProblemTypes","responses":{"200":{"description":"Problem types registry retrieved successfully. Returns a JSON object containing all problem types, organized by name and category, plus registry metadata.","content":{"application/json":{"examples":{"Complete Problem Types Registry":{"description":"Complete Problem Types Registry","value":{"problemTypes":{"VALIDATION_ERROR":{"uri":"https://developer.currencyguard.com/problems/validation/validation-error","category":"validation","title":"Validation Error","description":"The request contains invalid data that failed validation rules","httpStatus":400,"examples":["Invalid currency code format","Amount must be positive"]},"RESOURCE_NOT_FOUND":{"uri":"https://developer.currencyguard.com/problems/http/resource-not-found","category":"client","title":"Resource Not Found","description":"The requested resource does not exist or has been deleted","httpStatus":404,"examples":["Guard with specified ID not found","Currency pair does not exist"]},"AUTHENTICATION_FAILED":{"uri":"https://developer.currencyguard.com/problems/security/authentication-failed","category":"security","title":"Authentication Failed","description":"Authentication credentials are missing, invalid, or expired","httpStatus":401,"examples":["JWT token has expired","Invalid bearer token"]},"INSUFFICIENT_PERMISSIONS":{"uri":"https://developer.currencyguard.com/problems/security/insufficient-permissions","category":"security","title":"Insufficient Permissions","description":"Authenticated user lacks permission to perform the requested operation","httpStatus":403,"examples":["User does not have internal role","Cannot access resources from other companies"]}},"categories":{"validation":["VALIDATION_ERROR","MALFORMED_REQUEST"],"client":["RESOURCE_NOT_FOUND","RESOURCE_CONFLICT"],"security":["AUTHENTICATION_FAILED","INSUFFICIENT_PERMISSIONS","RATE_LIMIT_EXCEEDED"],"business":["GUARD_CREATION_FAILED","PRICING_FAILED","INVALID_STATE_TRANSITION"],"server":["INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","DATABASE_ERROR"]},"totalTypes":14,"version":"1.0","specificationVersion":"RFC 9457"}}}}}},"500":{"description":"Server error - internal processing failure — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/v1/problem-types/category/{category}":{"get":{"tags":["ProblemTypes"],"summary":"Get problem types by category","description":"Returns all problem types that belong to a specific category. Categories group related problem types together (e.g., validation, security, business, server). The response includes the category name, total count, and details for each problem type in that category including URI, title, description, and HTTP status. This endpoint is publicly accessible and does not require authentication.","operationId":"getProblemTypesByCategory","parameters":[{"name":"category","in":"path","description":"Category name in lowercase (e.g., validation, security, business, client, server). Categories group related problem types together for easier discovery and organization.","required":true,"schema":{"type":"string"},"example":"security"}],"responses":{"200":{"description":"Problem types for the specified category retrieved successfully. Returns all problem types organized under this category.","content":{"application/json":{"examples":{"Security Category Problem Types":{"description":"Security Category Problem Types","value":{"category":"security","totalTypes":3,"problemTypes":{"AUTHENTICATION_FAILED":{"uri":"https://developer.currencyguard.com/problems/security/authentication-failed","title":"Authentication Failed","description":"Authentication credentials are missing, invalid, or expired","httpStatus":401},"INSUFFICIENT_PERMISSIONS":{"uri":"https://developer.currencyguard.com/problems/security/insufficient-permissions","title":"Insufficient Permissions","description":"Authenticated user lacks permission to perform the requested operation","httpStatus":403},"RATE_LIMIT_EXCEEDED":{"uri":"https://developer.currencyguard.com/problems/security/rate-limit-exceeded","title":"Rate Limit Exceeded","description":"Request rate limit has been exceeded for this user or API key","httpStatus":429}}}}}}}},"404":{"description":"Category not found - the specified category does not exist or contains no problem types — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error - internal processing failure — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/v1/problem-types/{problemTypeName}":{"get":{"tags":["ProblemTypes"],"summary":"Get a specific RFC 9457 problem type","description":"Returns detailed information about a single problem type identified by its name. The response includes the problem type URI (environment-specific), category classification, title, description, associated HTTP status code, and usage examples. This endpoint is publicly accessible and does not require authentication.","operationId":"getProblemType","parameters":[{"name":"problemTypeName","in":"path","description":"Problem type name in uppercase snake_case format (e.g., VALIDATION_ERROR, RESOURCE_NOT_FOUND, AUTHENTICATION_FAILED). The name is case-sensitive and must match exactly as registered in the problem types registry.","required":true,"schema":{"type":"string"},"example":"VALIDATION_ERROR"}],"responses":{"200":{"description":"Problem type retrieved successfully. Returns complete details for the specified problem type.","content":{"application/json":{"examples":{"VALIDATION_ERROR Problem Type":{"description":"VALIDATION_ERROR Problem Type","value":{"name":"VALIDATION_ERROR","uri":"https://developer.currencyguard.com/problems/validation/validation-error","category":"validation","title":"Validation Error","description":"The request contains invalid data that failed validation rules","httpStatus":400,"examples":["Invalid currency code format","Amount must be positive","Required field is missing"]}}}}}},"404":{"description":"Problem type not found - the specified problem type name does not exist in the registry — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"500":{"description":"Server error - internal processing failure — [`server/internal-error`](/problems/server/internal-error/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/problems/{category}/{slug}":{"get":{"tags":["ProblemTypes"],"summary":"Resolve an RFC 9457 problem type URI","description":"Returns the definition of the problem type identified by a `type` URI carried on an error response, including its title, description, HTTP status and examples. Publicly accessible and does not require authentication.","operationId":"resolveProblemType","parameters":[{"name":"category","in":"path","description":"Problem category","required":true,"schema":{"type":"string"},"example":"business"},{"name":"slug","in":"path","description":"Problem type slug within the category","required":true,"schema":{"type":"string"},"example":"quote-expired"}],"responses":{"200":{"description":"Problem type found","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"404":{"description":"No problem type is registered at this path — [`http/resource-not-found`](/problems/http/resource-not-found/)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/sse/api-regulated/v1/stream":{"get":{"tags":["Messaging"],"summary":"Open the event stream","description":"Opens a Server-Sent Events connection and returns a session id on the first event. Nothing flows until you subscribe: use that session id with POST /subscriptions/{sessionId} to choose which message types this connection carries. One connection serves the whole session.","operationId":"stream_1","parameters":[{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/event-stream":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServerSentEventString"}}}}}}}},"/sse/api-regulated/v1/subscriptions/{sessionId}":{"post":{"tags":["Messaging"],"summary":"Subscribe this stream to a message type","description":"Adds a message type to an open stream. The session may live on another instance, so a subscription for a session this one does not hold is relayed rather than refused.","operationId":"addSubscription_1","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionKeyCLOCK"},{"$ref":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL"},{"$ref":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_OPTIONS"},{"$ref":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION"},{"$ref":"#/components/schemas/SubscriptionKeyFX_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARDS"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_QUOTES"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_DATA"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_STATUS"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS"},{"$ref":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE"}]}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string"}}}}}},"delete":{"tags":["Messaging"],"summary":"Remove all subscriptions from this stream","description":"Stops every message type on the session. The connection stays open and can be subscribed again.","operationId":"removeSubscriptions_1","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"StoredDocumentDTO":{"type":"object","properties":{"bucket":{"type":"string","description":"Bucket the document is stored in","example":"cg-s3-re-private-eeeeeeee-ee11-4001-8000-000000000000"},"entityId":{"type":"string","description":"ID of the entity this document belongs to","format":"uuid","example":"9f2c1b44-4c2e-4f3a-9b1e-2d5a7c8e1f00"},"documentType":{"type":"string","description":"Opaque type label supplied by the calling domain; never interpreted here","example":"CUSTOMER_AVATAR_FILE"},"documentId":{"type":"string","description":"The document's own stable id, carried in the storage key","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"versionId":{"type":"string","description":"Object-store version identifier for this revision","example":"a3e71ac1-d028-4ed9-932f-d04f956ebe17"},"contentType":{"type":"string","description":"MIME type, stored in the clear","example":"image/jpeg"},"size":{"type":"integer","description":"Size of the content in bytes","format":"int64","example":84213},"lastModified":{"type":"string","description":"When this revision was written, ISO-8601","example":"2026-07-26T12:35:53Z"},"metadata":{"type":"string","description":"The caller's encrypted metadata envelope, verbatim. Null when no metadata was stored, or when the sidecar is unreadable.","example":"{\"status\":\"ENCRYPTED\",\"value\":\"AQICAHh...\",\"key\":\"arn:aws:kms:...\"}"}},"description":"A stored document: where it lives, its size, and its opaque metadata envelope"},"JsonNode":{"type":"object","description":"UI preferences for this user, namespaced by section.","example":{"tables":{"guard-book":{"pageSize":50}}}},"UserDTOUpdate":{"type":"object","properties":{"subClaim":{"type":"string","description":"The unique identifier from JWT sub claim for this user.","example":"auth0|12345678-1234-4001-8000-123456789012"},"roleClaims":{"maxLength":500,"minLength":0,"type":"string","description":"The role claims for this user as a concatenated string.","example":"ROLE_ADMIN,ROLE_TRADER"},"status":{"type":"string","description":"The status of this user account.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"entitlementsTemplateId":{"type":"string","description":"The entitlements template assigned to this user.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"piiData":{"$ref":"#/components/schemas/UserDTOUpdatePiiData"}},"description":"Customer update data"},"UserDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this user.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"subClaim":{"type":"string","description":"The unique identifier from JWT sub claim for this user.","example":"auth0|12345678-1234-4001-8000-123456789012"},"roleClaims":{"maxLength":500,"minLength":0,"type":"string","description":"The role claims for this user as a concatenated string.","example":"ROLE_ADMIN,ROLE_TRADER"},"status":{"type":"string","description":"The status of this user account.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"onboardedDate":{"type":"string","description":"The date when the user was onboarded.","example":"2024-01-15T00:00:00Z"},"entitlementsTemplateId":{"type":"string","description":"The entitlements template assigned to this user.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"piiData":{"$ref":"#/components/schemas/UserDTOPiiData"},"preferences":{"$ref":"#/components/schemas/UserDTOPreferences"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this user's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"authType":{"type":"string","description":"The authentication type for this user. OAUTH2_AUTHORIZATION_CODE for interactive human users, OAUTH2_CLIENT_CREDENTIALS for machine-to-machine API clients.","example":"OAUTH2_AUTHORIZATION_CODE"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a User"},"CompanyDTOUpdate":{"type":"object","properties":{"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this company belongs to.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"piiData":{"$ref":"#/components/schemas/CompanyDTOUpdatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this company's users authenticate against, shared with its broker.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The company's functional/home currency (ISO 4217). Defaults the guard currency for this company's guards.","example":"GBP"}},"description":"Updated company data"},"CompanyDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this company.","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this company belongs to.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this company belongs to.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"status":{"type":"string","description":"The status of this company.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"piiData":{"$ref":"#/components/schemas/CompanyDTOPiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this company's users authenticate against, shared with its broker.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The company's functional/home currency (ISO 4217). Defaults the guard currency for this company's guards.","example":"GBP"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Company"},"EntityVariableDTOUpsert":{"required":["name"],"type":"object","properties":{"name":{"maxLength":64,"minLength":0,"pattern":"[A-Z0-9_]+","type":"string","description":"The variable name. Uppercase letters, digits and underscores only. Names ending in _PASSWORD, _SECRET, _TOKEN or _KEY are treated as secret and obscured on screen until revealed.","example":"TRANSFERMATE_PASSWORD"},"value":{"maxLength":512,"minLength":0,"type":"string","description":"The value to store.","example":"s3cret-from-transfermate"}},"description":"Set or replace one company variable."},"EntityVariableDTO":{"type":"object","properties":{"name":{"type":"string","description":"The variable name.","example":"TRANSFERMATE_USERNAME"},"value":{"type":"string","description":"The value. Returned for secret variables too — this endpoint is the one place a credential is served, and clients are expected to obscure it until the user reveals it.","example":"FASTER_PAYMENTS"},"secret":{"type":"boolean","description":"Whether this variable is a credential and must be obscured on screen until revealed. True for any name ending in _PASSWORD, _SECRET, _TOKEN or _KEY.","example":false}},"description":"A named variable held against a company, broker or regulated entity. Secret variables carry their value and are flagged so clients obscure it on screen."},"RegulatedEntityDTOUpdate":{"type":"object","properties":{"piiData":{"$ref":"#/components/schemas/RegulatedEntityDTOUpdatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this regulated entity's staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000001"}},"description":"Updated regulated entity data"},"RegulatedEntityDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this regulated entity.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"entityReferenceCode":{"pattern":"^[A-Z0-9]{2}$","type":"string","description":"Two-character code identifying this regulated entity in customer-facing references, e.g. the 'SP' in Guard reference GSP1000104. Immutable once a Guard has been issued under it.","example":"SP"},"piiData":{"$ref":"#/components/schemas/RegulatedEntityDTOPiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this regulated entity's staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000001"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a RegulatedEntity"},"InvitationTemplateDTOUpdate":{"type":"object","properties":{"entitlementsTemplateId":{"type":"string","description":"The entitlements template this invitation template is linked to.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"invitationEmailMessage":{"type":"string","description":"The full HTML email body template for invitation emails. Supports variable placeholders: ${firstName}, ${lastName}, ${regulatedEntityName}, ${introducingBrokerName}, ${currencyGuardCompanyName}, ${acceptanceUrl}, ${currentYear}, and logo variables.","example":"<p>Dear ${firstName},</p><p>Welcome to CurrencyGuard!</p>"},"invitationEmailSubject":{"maxLength":200,"minLength":0,"type":"string","description":"The invitation email subject line template with variable placeholders.","example":"Welcome to CurrencyGuard"}},"description":"Schema for representing a InvitationTemplate"},"InvitationTemplateDTO":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the invitation template.","format":"uuid","example":"660f9511-f3bc-52f6-c938-668877662111"},"entitlementsTemplateId":{"type":"string","description":"The entitlements template this invitation template is linked to.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"invitationEmailMessage":{"type":"string","description":"The full HTML email body template for invitation emails. Supports variable placeholders: ${firstName}, ${lastName}, ${regulatedEntityName}, ${introducingBrokerName}, ${currencyGuardCompanyName}, ${acceptanceUrl}, ${currentYear}, and logo variables.","example":"<p>Dear ${firstName},</p><p>Welcome to CurrencyGuard!</p>"},"invitationEmailSubject":{"maxLength":200,"minLength":0,"type":"string","description":"The invitation email subject line template with variable placeholders.","example":"Welcome to CurrencyGuard"},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a InvitationTemplate"},"IntroducingBrokerDTOUpdate":{"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this introducing broker belongs to.","format":"uuid","example":"eeeeeeee-ee11-4001-8000-000000000000"},"piiData":{"$ref":"#/components/schemas/IntroducingBrokerDTOUpdatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this broker's own staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000002"},"customerOauthPoolId":{"type":"string","description":"The OAuth pool the customers of this broker's companies authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"}},"description":"Schema for representing a IntroducingBroker"},"IntroducingBrokerDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this introducing broker.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this introducing broker belongs to.","format":"uuid","example":"eeeeeeee-ee11-4001-8000-000000000000"},"status":{"type":"string","description":"The status of this introducing broker.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"piiData":{"$ref":"#/components/schemas/IntroducingBrokerDTOPiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this broker's own staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000002"},"customerOauthPoolId":{"type":"string","description":"The OAuth pool the customers of this broker's companies authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a IntroducingBroker"},"EntitlementsTemplateDTOUpdate":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the entitlements template.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"templateName":{"type":"string","description":"The unique name of the entitlements template.","example":"Super User"},"description":{"type":"string","description":"Description of what this template provides.","example":"Full administrative access with all permissions"},"userType":{"type":"string","description":"The user type this template applies to.","example":"REGULATED","enum":["INTERNAL","REGULATED","CUSTOMER","SALES"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"isActive":{"type":"boolean","description":"Whether this template is active and can be assigned to users.","example":true}},"description":"Schema for representing a EntitlementsTemplate"},"EntitlementsTemplateDTO":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the entitlements template.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"templateName":{"type":"string","description":"The unique name of the entitlements template.","example":"Super User"},"description":{"type":"string","description":"Description of what this template provides.","example":"Full administrative access with all permissions"},"userType":{"type":"string","description":"The user type this template applies to.","example":"REGULATED","enum":["INTERNAL","REGULATED","CUSTOMER","SALES"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"isActive":{"type":"boolean","description":"Whether this template is active and can be assigned to users.","example":true},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a EntitlementsTemplate"},"ConfirmationTemplateDTOUpdate":{"type":"object","properties":{"id":{"type":"string","description":"Unique template identifier","format":"uuid","example":"a0000000-0000-4000-8000-000000000001"},"documentType":{"type":"string","description":"Document type","example":"GUARD_CONFIRMATION"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID — NULL means default template","format":"uuid"},"templateName":{"type":"string","description":"Human-readable template name","example":"Default Guard Confirmation v1"},"templateBody":{"type":"string","description":"HTML template body with variable placeholders"},"effectiveFrom":{"type":"string","description":"Date from which this template version is effective","example":"2026-01-01T00:00:00Z"},"eventSequence":{"type":"integer","description":"Event sequence number for event-driven processing","format":"int64"},"versionNumber":{"type":"integer","description":"Optimistic locking version number","format":"int32","example":1},"updatedBy":{"type":"string","description":"User who last updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of last update in UTC","example":"2026-01-01T00:00:00Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2026-01-01T00:00:00Z"}},"description":"Schema for representing a ConfirmationTemplate"},"ConfirmationTemplateDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique template identifier","format":"uuid","example":"a0000000-0000-4000-8000-000000000001"},"documentType":{"type":"string","description":"Document type","example":"GUARD_CONFIRMATION"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID — NULL means default template","format":"uuid"},"templateName":{"type":"string","description":"Human-readable template name","example":"Default Guard Confirmation v1"},"templateBody":{"type":"string","description":"HTML template body with variable placeholders"},"effectiveFrom":{"type":"string","description":"Date from which this template version is effective","example":"2026-01-01T00:00:00Z"},"eventSequence":{"type":"integer","description":"Event sequence number for event-driven processing","format":"int64"},"versionNumber":{"type":"integer","description":"Optimistic locking version number","format":"int32","example":1},"updatedBy":{"type":"string","description":"User who last updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of last update in UTC","example":"2026-01-01T00:00:00Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2026-01-01T00:00:00Z"}},"description":"Schema for representing a ConfirmationTemplate"},"EventSubscriptionRegisterRequestDTO":{"required":["callbackUrl"],"type":"object","properties":{"callbackUrl":{"maxLength":500,"minLength":0,"type":"string","description":"Endpoint to which signed event batches will be POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/trade"},"maxBatchSize":{"minimum":1,"type":"integer","description":"Maximum number of events the dispatcher will put in one batch. Omit to leave unchanged.","format":"int32","nullable":true,"example":100}},"description":"Request data for renewing an internal event subscription"},"EventSubscriptionCreatedDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID of the created subscription. The subscriber uses this for renewals and replays.","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"streamName":{"type":"string","description":"The feed this subscription consumes","example":"trade"},"subscriberName":{"type":"string","description":"Name of the consuming processor","example":"LedgerJournalFeedConsumer"},"callbackUrl":{"type":"string","description":"Endpoint to which signed event batches will be POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/trade"},"status":{"type":"string","description":"Subscription status","example":"ACTIVE"},"lastEventSequence":{"type":"integer","description":"Cursor the subscription starts from. Events with a greater sequence are delivered.","format":"int64","example":4812},"maxBatchSize":{"type":"integer","description":"Maximum number of events the dispatcher will put in one batch","format":"int32","example":100},"signingSecret":{"type":"string","description":"HMAC-SHA256 signing secret. Returned on creation and on renewal so a restarted subscriber can recover it without persisting a copy; redacted from list and get responses.","example":"whsec_3J8x...redacted..."},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2026-06-13T12:30:40Z"},"message":{"type":"string","description":"Human-readable note about the one-time secret"}},"description":"Internal subscription details including the one-time signing secret"},"UpdateScheduleRequest":{"type":"object","properties":{"cronExpression":{"type":"string"},"timeZone":{"type":"string"}}},"TradingConfigurationUpdateDTO":{"required":["value"],"type":"object","properties":{"value":{"type":"string","description":"The new value, as a string in the key's configured type","example":"0.0055"}},"description":"Update to a trading configuration value"},"TradeEventProcessingRuleDTOUpsert":{"required":["description","eventName","eventSource","eventType","processingType","ruleVersion","rules","trigger"],"type":"object","properties":{"ruleVersion":{"type":"string","description":"Rule version identifier","example":"JERv1"},"eventSource":{"type":"string","description":"Event source this rule applies to","example":"TRADING"},"eventType":{"type":"string","description":"Event type this rule applies to","example":"Guard"},"processingType":{"type":"string","description":"Type of processing this rule performs","example":"JournalEntryProcessing"},"eventName":{"type":"string","description":"Human-readable name for this event","example":"Guard Becomes Active"},"description":{"type":"string","description":"Detailed description of what this rule does","example":"Process Guard activation event and recognize fee revenue"},"trigger":{"$ref":"#/components/schemas/TradeEventProcessingRuleDTOUpsertTrigger"},"rules":{"$ref":"#/components/schemas/TradeEventProcessingRuleDTOUpsertRules"}},"description":"Schema for representing a TradeEventProcessingRule"},"TradeEventProcessingRuleDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this trade event processing rule","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"ruleVersion":{"type":"string","description":"Rule version identifier","example":"JERv1"},"eventSource":{"type":"string","description":"Event source this rule applies to","example":"TRADING"},"eventType":{"type":"string","description":"Event type this rule applies to","example":"Guard"},"processingType":{"type":"string","description":"Type of processing this rule performs","example":"JournalEntryProcessing"},"eventName":{"type":"string","description":"Human-readable name for this event","example":"Guard Becomes Active"},"description":{"type":"string","description":"Detailed description of what this rule does","example":"Process Guard activation event and recognize fee revenue"},"trigger":{"$ref":"#/components/schemas/TradeEventProcessingRuleDTOTrigger"},"rules":{"$ref":"#/components/schemas/TradeEventProcessingRuleDTORules"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a TradeEventProcessingRule"},"TradeEventProcessingRuleVersionDTOUpdate":{"type":"object","properties":{"ruleVersion":{"type":"string","description":"Rule version identifier","example":"JERv1"},"description":{"type":"string","description":"Description of this rule version","example":"JournalEntry Entry Rule version 1"},"effectiveFrom":{"type":"string","description":"Date from which this rule version is effective","example":"2025-01-01T00:00:00Z"},"deprecatedAt":{"type":"string","description":"Date when this rule version was deprecated (null if still active)","example":"2025-12-31T23:59:59Z"}},"description":"Schema for representing a TradeEventProcessingRuleVersion"},"TradeEventProcessingRuleVersionDTO":{"type":"object","properties":{"ruleVersion":{"type":"string","description":"Rule version identifier","example":"JERv1"},"description":{"type":"string","description":"Description of this rule version","example":"JournalEntry Entry Rule version 1"},"effectiveFrom":{"type":"string","description":"Date from which this rule version is effective","example":"2025-01-01T00:00:00Z"},"deprecatedAt":{"type":"string","description":"Date when this rule version was deprecated (null if still active)","example":"2025-12-31T23:59:59Z"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a TradeEventProcessingRuleVersion"},"RingfencePolicyDTO":{"type":"object","properties":{"autoRingfenceRegulatedEntity":{"type":"boolean","description":"Give each new regulated entity its own key, role and document store.","example":false},"autoRingfenceIntroducingBroker":{"type":"boolean","description":"Give each new introducing broker its own key, role and document store.","example":false},"autoRingfenceCompany":{"type":"boolean","description":"Give each new company its own key, role and document store.","example":false}},"description":"Whether new entities inside a perimeter are given perimeters of their own"},"TenantPerimeterDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this tenant perimeter.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"awsPiiKmsKeyArn":{"type":"string","description":"KMS key ARN used to ENCRYPT pii_data for rows in this perimeter. Decryption uses the key recorded in each blob, not this one.","example":"arn:aws:kms:eu-west-2:123456789012:key/abc-123-def-456"},"awsIamRoleArn":{"type":"string","description":"IAM role ARN that users of this perimeter federate to when exchanging their JWT for AWS credentials.","example":"arn:aws:iam::123456789012:role/cg-perimeter-role"},"awsS3Bucket":{"type":"string","description":"S3 bucket holding this perimeter's documents. CurrencyGuard staff are granted no read access; the platform itself retains access, since it performs the uploads and downloads.","example":"cg-s3-cccccccc-cc11-4001-8000-000000000000"},"awsPreviousKmsKeyArn":{"type":"string","description":"Key that rows in this perimeter may still be encrypted under while a sweep is unfinished. NULL when fully converged.","example":"arn:aws:kms:eu-west-2:123456789012:key/old-999"},"awsPreviousS3Bucket":{"type":"string","description":"Bucket that objects in this perimeter may still live in while a sweep is unfinished. Reads fall back to it while non-null. NULL when fully converged.","example":"cg-s3-re-private-eeeeeeee-ee11-4001-8000-000000000000"},"ancestorAccess":{"type":"boolean","description":"Whether every ancestor perimeter's role may read and write this perimeter's key and bucket.","example":true},"autoRingfenceRegulatedEntity":{"type":"boolean","description":"Whether a new regulated entity inside this perimeter is given one of its own.","example":false},"autoRingfenceIntroducingBroker":{"type":"boolean","description":"Whether a new introducing broker inside this perimeter is given one of its own.","example":false},"autoRingfenceCompany":{"type":"boolean","description":"Whether a new company inside this perimeter is given one of its own.","example":false},"rootEntityType":{"type":"string","description":"Which level of the tenant hierarchy this perimeter was created for.","example":"INTRODUCING_BROKER"},"rootEntityId":{"type":"string","description":"The entity this perimeter was created for.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"awsKeyDestroyedAt":{"type":"string","description":"When a scheduled key destruction becomes irreversible. Null unless the perimeter is DESTROYING.","example":"2026-08-31T00:00:00Z"},"status":{"type":"string","description":"Lifecycle and saga state. Anything other than ACTIVE means an operation is in flight.","example":"ACTIVE","enum":["PROVISIONING","SWEEPING","ACTIVE","RETIRING","RETIRED","DESTROYING","DESTROYED"]},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a TenantPerimeter"},"RailDTOUpsert":{"required":["adapter","baseUrl","regulatedEntityId"],"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"The regulated entity this connection belongs to. Must already be replicated into cgp.","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"adapter":{"maxLength":30,"minLength":0,"type":"string","description":"The adapter that carries this rail's traffic","example":"WISE"},"baseUrl":{"maxLength":255,"minLength":0,"type":"string","description":"The provider host this instance talks to","example":"https://api.wise-sandbox.com"},"credentialRef":{"maxLength":100,"minLength":0,"type":"string","description":"Secrets Manager entry holding this instance's credentials. Null for a rail that authenticates as nobody.","example":"currencyguard/wise"},"accountReference":{"maxLength":100,"minLength":0,"type":"string","description":"The provider's identifier for our account, where the rail needs one","example":"28104372"},"webhookKey":{"maxLength":255,"minLength":0,"type":"string","description":"Shared secret verifying this rail's inbound webhooks"}},"description":"A payment rail instance to create or replace"},"MaskedCredentialDTO":{"type":"object","properties":{"field":{"type":"string","description":"The field name within the secret","example":"api.password"},"masked":{"type":"string","description":"The value, masked to a tail","example":"••••••••9eaea5"}},"description":"One credential field, masked to a tail","example":[]},"RailViewDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID of this rail instance","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"regulatedEntityId":{"type":"string","description":"The regulated entity this connection belongs to","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"adapter":{"type":"string","description":"The adapter that carries its traffic","example":"TRANSFERMATE"},"baseUrl":{"type":"string","description":"The provider host it talks to","example":"http://mock-transfermate:8090"},"credentialRef":{"type":"string","description":"Secrets Manager entry holding its credentials","example":"currencyguard/transfermate"},"accountReference":{"type":"string","description":"The provider's id for our account, where the rail needs one","example":"28104372"},"active":{"type":"boolean","description":"Whether it may be chosen for new work","example":true},"walletsSupported":{"type":"boolean","description":"An adapter exists that can read balances on this rail","example":true},"paymentsSupported":{"type":"boolean","description":"An adapter exists that can instruct payments on this rail","example":true},"beneficiariesSupported":{"type":"boolean","description":"An adapter exists that can read beneficiaries on this rail","example":true},"statementsSupported":{"type":"boolean","description":"An adapter exists that can read account activity on this rail","example":true},"statementPullSupported":{"type":"boolean","description":"Activity can be fetched for a period on this rail","example":true},"statementUploadSupported":{"type":"boolean","description":"A statement document can be uploaded and read for this rail","example":false},"conversionsSupported":{"type":"boolean","description":"An adapter exists that can convert between wallets on this rail","example":true},"conversionQuoteIsBinding":{"type":"boolean","description":"A conversion quote on this rail can be executed as quoted","example":false},"walletProvisioningSupported":{"type":"boolean","description":"A wallet can be opened on this rail in a new currency","example":true},"walletRenameSupported":{"type":"boolean","description":"A wallet on this rail can be renamed","example":true},"credentials":{"type":"array","description":"Each credential the secret holds, masked","example":[],"items":{"$ref":"#/components/schemas/MaskedCredentialDTO"}},"credentialError":{"type":"string","description":"Why the credentials could not be read, when they could not","example":"currencyguard/wise not found"}},"description":"A payment rail instance: one PSP's connection to one provider"},"TradeEventPaymentObligationRuleDTOUpsert":{"type":"object","properties":{"ruleVersion":{"type":"string","description":"Rule set version identifier","example":"SETv1"},"eventType":{"type":"string","description":"Trade event type this rule applies to","example":"Guard"},"ruleName":{"type":"string","description":"Human-readable name","example":"Guard Fee Receivable"},"description":{"type":"string","description":"What this rule does and why"},"trigger":{"$ref":"#/components/schemas/TradeEventPaymentObligationRuleDTOUpsertTrigger"},"rules":{"$ref":"#/components/schemas/TradeEventPaymentObligationRuleDTOUpsertRules"},"autoApprove":{"type":"boolean","description":"Whether payments raised by this rule skip the maker-checker gate","example":true},"autoApproveLimit":{"type":"number","description":"Ceiling above which auto-approval no longer applies","example":250000},"isActive":{"type":"boolean","description":"Whether this rule is currently active","example":true}},"description":"Schema for representing a TradeEventPaymentObligationRule"},"TradeEventPaymentObligationRuleDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this rule","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"ruleVersion":{"type":"string","description":"Rule set version identifier","example":"SETv1"},"eventType":{"type":"string","description":"Trade event type this rule applies to","example":"Guard"},"ruleName":{"type":"string","description":"Human-readable name","example":"Guard Fee Receivable"},"description":{"type":"string","description":"What this rule does and why"},"trigger":{"$ref":"#/components/schemas/TradeEventPaymentObligationRuleDTOTrigger"},"rules":{"$ref":"#/components/schemas/TradeEventPaymentObligationRuleDTORules"},"autoApprove":{"type":"boolean","description":"Whether payments raised by this rule skip the maker-checker gate","example":true},"autoApproveLimit":{"type":"number","description":"Ceiling above which auto-approval no longer applies","example":250000},"isActive":{"type":"boolean","description":"Whether this rule is currently active","example":true},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a TradeEventPaymentObligationRule"},"RailBeneficiaryMappingDTOCreate":{"type":"object","properties":{"railInstanceId":{"type":"string","description":"The rail instance whose address book this id lives in","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"payeeCompanyId":{"type":"string","description":"The company this maps to, when the payee is one","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"payeeRegulatedEntityId":{"type":"string","description":"The regulated entity this maps to, when the payee is one","format":"uuid","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"payeeSelfRail":{"maxLength":30,"minLength":0,"type":"string","description":"The destination rail code, when the payee is ourselves at another rail","example":"WISE_PLATFORM_API"},"currencyCode":{"maxLength":3,"minLength":0,"type":"string","description":"ISO 4217 currency this mapping is scoped to, null if the rail is not currency-scoped","example":"GBP"},"railBeneficiaryId":{"maxLength":100,"minLength":0,"type":"string","description":"The rail's own identifier for this payee","example":"TM-BEN-448210"}},"description":"Schema for representing a RailBeneficiaryMapping"},"RailBeneficiaryMappingDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this mapping","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"railInstanceId":{"type":"string","description":"The rail instance whose address book this id lives in","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"payeeCompanyId":{"type":"string","description":"The company this maps to, when the payee is one","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"payeeRegulatedEntityId":{"type":"string","description":"The regulated entity this maps to, when the payee is one","format":"uuid","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"payeeSelfRail":{"maxLength":30,"minLength":0,"type":"string","description":"The destination rail code, when the payee is ourselves at another rail","example":"WISE_PLATFORM_API"},"currencyCode":{"maxLength":3,"minLength":0,"type":"string","description":"ISO 4217 currency this mapping is scoped to, null if the rail is not currency-scoped","example":"GBP"},"railBeneficiaryId":{"maxLength":100,"minLength":0,"type":"string","description":"The rail's own identifier for this payee","example":"TM-BEN-448210"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a RailBeneficiaryMapping"},"MfaSettingDTO":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether TOTP MFA is required for every user of this pool","example":true}},"description":"A pool's MFA setting"},"TradingControlRequest":{"required":["enabled"],"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the control flag should be enabled","example":true}},"description":"Request body with enabled flag"},"MarketStatusDTO":{"type":"object","properties":{"currentDateTime":{"type":"string","description":"The current date and time from the server clock in ISO8601 format","example":"2025-12-26T14:30:00Z"},"marketStatus":{"type":"string","description":"The current market status (OPEN or CLOSED)","example":"CLOSED","enum":["OPEN","CLOSED"]},"marketStatusReason":{"type":"string","description":"Reason for the current market status","example":"Boxing Day"},"reopenDateTime":{"type":"string","description":"The date and time when the market will next reopen in ISO8601 format (only present when market is currently closed)","nullable":true,"example":"2025-12-29T08:00:00Z"},"closeDateTime":{"type":"string","description":"The date and time when the market will next close in ISO8601 format","nullable":true,"example":"2025-12-29T16:00:00Z"},"canTrade":{"type":"boolean","description":"Master switch indicating whether trading is currently enabled globally","example":true},"canTradeOutsideOpeningHours":{"type":"boolean","description":"Whether trading is allowed outside configured operating hours","example":false},"calendarTimezone":{"type":"string","description":"IANA timezone ID used to interpret operating hours (e.g. 'Europe/London'). Clients should use this when displaying open/close times.","example":"Europe/London"},"upcomingSchedule":{"type":"array","description":"The upcoming 7-day calendar schedule showing open/closed status, operating hours, and holiday information","items":{"$ref":"#/components/schemas/MarketStatusDailyScheduleDTO"}}},"description":"Schema for representing current market status and upcoming trading schedule"},"MarketStatusDailyScheduleDTO":{"type":"object","properties":{"date":{"type":"string","description":"The date for this schedule entry in ISO8601 format","example":"2025-12-26T00:00:00Z"},"dayOfWeek":{"type":"string","description":"Day of week name","example":"Friday"},"marketStatus":{"type":"string","description":"Market status for this day (OPEN or CLOSED)","example":"CLOSED","enum":["OPEN","CLOSED"]},"open":{"type":"string","description":"Opening time in HH:mm format (only present if marketStatus is OPEN)","nullable":true,"example":"08:00"},"close":{"type":"string","description":"Closing time in HH:mm format (only present if marketStatus is OPEN)","nullable":true,"example":"16:00"},"holiday":{"type":"string","description":"Holiday name if this is a holiday (only present if marketStatus is CLOSED and it's a holiday)","nullable":true,"example":"Boxing Day"}},"description":"Schema for representing a single day in the market trading schedule"},"HeadlessPasswordToggleRequestDTO":{"required":["enabled"],"type":"object","properties":{"enabled":{"type":"boolean"}}},"HeadlessPasswordStatusDTO":{"type":"object","properties":{"enabled":{"type":"boolean"},"toggleable":{"type":"boolean"}}},"InterestRateCurveQuoteDTOUpsert":{"required":["currencyCode","model","source","valuationDatetime"],"type":"object","properties":{"id":{"type":"string","description":"ID for this interest rate curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyCode":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code this curve applies to","example":"GBP"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the curve data","example":"MANUAL"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/InterestRateCurveQuoteDTOUpsertModel"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a InterestRateCurveQuote"},"InterestRateCurveQuoteDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this interest rate curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyCode":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code this curve applies to","example":"GBP"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the curve data","example":"MANUAL"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/InterestRateCurveQuoteDTOModel"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a InterestRateCurveQuote"},"GuardMarginScheduleDTOUpdate":{"type":"object","properties":{"id":{"type":"string","description":"ID for this guard margin schedule","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID for entity-specific schedules. NULL = applies to all entities","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for pair-specific schedules. NULL = applies to all currency pairs","example":"GBPUSD"},"marginSchedule":{"$ref":"#/components/schemas/GuardMarginScheduleDTOUpdateMarginSchedule"}},"description":"Guard margin schedule update data"},"GuardMarginScheduleDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this guard margin schedule","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID for entity-specific schedules. NULL = applies to all entities","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for pair-specific schedules. NULL = applies to all currency pairs","example":"GBPUSD"},"marginSchedule":{"$ref":"#/components/schemas/GuardMarginScheduleDTOMarginSchedule"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a GuardMarginSchedule"},"FXVolSurfaceQuoteDTOUpsert":{"required":["currencyPair","model","source","valuationDatetime"],"type":"object","properties":{"id":{"type":"string","description":"ID for this volatility surface","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this volatility surface","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"The instant this surface is valued at, in UTC. The vendor's own time where they assert one, otherwise the instant the cutoff designates. Not a rounded cutoff time -- see the note above this table","example":"2024-02-11T09:00:02Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Label designating this surface as the official marks for a valuation point. Vendor-stated where given, otherwise derived from valuation_datetime","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXVolSurfaceQuoteDTOUpsertModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the volatility surface data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1}},"description":"Schema for representing a FXVolSurfaceQuote"},"FXVolSurfaceQuoteDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this volatility surface","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this volatility surface","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"The instant this surface is valued at, in UTC. The vendor's own time where they assert one, otherwise the instant the cutoff designates. Not a rounded cutoff time -- see the note above this table","example":"2024-02-11T09:00:02Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Label designating this surface as the official marks for a valuation point. Vendor-stated where given, otherwise derived from valuation_datetime","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXVolSurfaceQuoteDTOModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the volatility surface data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXVolSurfaceQuote"},"ManualPriceRequestDTO":{"required":["ask","bid"],"type":"object","properties":{"bid":{"pattern":"\\d+(\\.\\d+)?","type":"string"},"ask":{"pattern":"\\d+(\\.\\d+)?","type":"string"}}},"FXPriceData":{"type":"object","properties":{"currencyPair":{"type":"string"},"bid":{"type":"number"},"ask":{"type":"number"},"timestamp":{"type":"string","format":"date-time"}}},"FXPriceResponse":{"type":"object","properties":{"isValid":{"type":"boolean"},"price":{"$ref":"#/components/schemas/FXPriceData"},"subscriptionSource":{"type":"string"},"emissionSource":{"type":"string"}}},"FXForwardCurveQuoteDTOUpsert":{"required":["currencyPair","model","source","valuationDatetime"],"type":"object","properties":{"id":{"type":"string","description":"ID for this forward point curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this forward point curve","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this forward curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXForwardCurveQuoteDTOUpsertModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the forward point curve data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1}},"description":"Schema for representing a FXForwardCurveQuote"},"FXForwardCurveQuoteDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this forward point curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this forward point curve","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this forward curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXForwardCurveQuoteDTOModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the forward point curve data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXForwardCurveQuote"},"CurrencyguardCompanyDTOUpdate":{"type":"object","properties":{"companyName":{"maxLength":200,"minLength":4,"type":"string","description":"The company name.","example":"CurrencyGuard Limited"},"registeredCompanyNumber":{"maxLength":20,"minLength":1,"type":"string","description":"The registered company number.","example":"12345678"},"contactEmail":{"maxLength":100,"minLength":0,"type":"string","description":"The main contact email address.","example":"info@currencyguard.co.uk"},"websiteUrl":{"maxLength":200,"minLength":0,"type":"string","description":"The company website URL.","example":"https://www.currencyguard.co.uk"},"phoneNumber":{"maxLength":20,"minLength":0,"pattern":"^\\+?[1-9]\\d{1,14}$","type":"string","description":"The primary contact phone number.","example":"+44 7768 298148"},"addressLine1":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 1.","example":"CurrencyGuard House"},"addressLine2":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 2.","example":"123 Financial District"},"city":{"maxLength":50,"minLength":0,"type":"string","description":"The head office city.","example":"London"},"stateProvince":{"maxLength":50,"minLength":0,"type":"string","description":"The head office state/province.","example":"England"},"postcode":{"maxLength":15,"minLength":0,"type":"string","description":"The head office postcode.","example":"EC2A 4DP"},"countryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"The head office country code.","example":"GB"},"companyLogoDocumentId":{"type":"string","description":"The company logo document.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"The calendar code for this company's trading operations.","example":"GBLO"},"calendarTimezone":{"maxLength":50,"minLength":0,"type":"string","description":"The timezone for this company's trading operations.","example":"Europe/London"},"operatingHours":{"$ref":"#/components/schemas/CurrencyguardCompanyDTOUpdateOperatingHours"},"isActive":{"type":"boolean","description":"Whether CurrencyGuard company record is active.","example":true},"oauthPoolId":{"type":"string","description":"The OAuth pool CurrencyGuard staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000004"},"systemOauthPoolId":{"type":"string","description":"The OAuth pool system accounts authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000005"}},"description":"Updated CurrencyGuard company data"},"CurrencyguardCompanyDTOInternal":{"type":"object","properties":{"id":{"type":"string","description":"The ID for CurrencyGuard company.","format":"uuid","example":"00000000-0000-4000-8000-000000000000"},"companyName":{"maxLength":200,"minLength":4,"type":"string","description":"The company name.","example":"CurrencyGuard Limited"},"registeredCompanyNumber":{"maxLength":20,"minLength":1,"type":"string","description":"The registered company number.","example":"12345678"},"contactEmail":{"maxLength":100,"minLength":0,"type":"string","description":"The main contact email address.","example":"info@currencyguard.co.uk"},"websiteUrl":{"maxLength":200,"minLength":0,"type":"string","description":"The company website URL.","example":"https://www.currencyguard.co.uk"},"phoneNumber":{"maxLength":20,"minLength":0,"pattern":"^\\+?[1-9]\\d{1,14}$","type":"string","description":"The primary contact phone number.","example":"+44 7768 298148"},"addressLine1":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 1.","example":"CurrencyGuard House"},"addressLine2":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 2.","example":"123 Financial District"},"city":{"maxLength":50,"minLength":0,"type":"string","description":"The head office city.","example":"London"},"stateProvince":{"maxLength":50,"minLength":0,"type":"string","description":"The head office state/province.","example":"England"},"postcode":{"maxLength":15,"minLength":0,"type":"string","description":"The head office postcode.","example":"EC2A 4DP"},"countryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"The head office country code.","example":"GB"},"companyLogoDocumentId":{"type":"string","description":"The company logo document.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"The calendar code for this company's trading operations.","example":"GBLO"},"calendarTimezone":{"maxLength":50,"minLength":0,"type":"string","description":"The timezone for this company's trading operations.","example":"Europe/London"},"operatingHours":{"$ref":"#/components/schemas/CurrencyguardCompanyDTOInternalOperatingHours"},"isActive":{"type":"boolean","description":"Whether CurrencyGuard company record is active.","example":true},"oauthPoolId":{"type":"string","description":"The OAuth pool CurrencyGuard staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000004"},"systemOauthPoolId":{"type":"string","description":"The OAuth pool system accounts authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000005"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"system"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a CurrencyguardCompany"},"CurrencyPairDTOUpdate":{"type":"object","properties":{"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"6-character code for the currency pair","example":"GBPUSD"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency code","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency code","example":"USD"},"isActive":{"type":"boolean","description":"Whether this currency pair is active for trading","example":true},"fwdRoute":{"type":"string","description":"How this pair's forward curve is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"DIRECT","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"volRoute":{"type":"string","description":"How this pair's volatility surface is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"USD_CROSS","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"historicDataSource":{"type":"string","description":"External source that owns this pair's daily close price history.","example":"BOE","enum":["BOE","FRED","HKMA","UNKNOWN"]},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Additional calendar code for settlement holidays (e.g., USNY for cross-currency pairs)","example":"USNY"},"spotLagDays":{"maximum":2,"minimum":1,"type":"integer","description":"FX spot settlement lag in business days (T+N). 2 for most pairs; 1 for USD T+1 pairs such as USDCAD, USDTRY, USDPHP, USDRUB. Drives value/settlement date derivation.","format":"int32","example":2},"guardEnabled":{"type":"boolean","description":"Whether CurrencyGuard sells Guards on this pair. A commercial decision, separate from is_active (live rates wanted) and from whether the pair can be priced (a vol surface route with a spread multiplier). New pairs default to false so offering one is deliberate.","example":true}},"description":"Currency pair update data"},"CurrencyPairDTO":{"type":"object","properties":{"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"6-character code for the currency pair","example":"GBPUSD"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency code","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency code","example":"USD"},"pipPrecision":{"maximum":5,"minimum":0,"type":"integer","description":"Number of decimal places for pip precision","format":"int32","example":4},"useFractionalPips":{"type":"boolean","description":"Whether this pair uses fractional pips","example":true},"totalPrecision":{"maximum":6,"minimum":0,"type":"integer","description":"Total precision including fractional pips","format":"int32","example":5},"isActive":{"type":"boolean","description":"Whether this currency pair is active for trading","example":true},"isMarketConvention":{"type":"boolean","description":"Whether this pair follows market convention (true) or is inverted (false)","example":true},"fwdRoute":{"type":"string","description":"How this pair's forward curve is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"DIRECT","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"volRoute":{"type":"string","description":"How this pair's volatility surface is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"USD_CROSS","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"historicDataSource":{"type":"string","description":"External source that owns this pair's daily close price history.","example":"BOE","enum":["BOE","FRED","HKMA","UNKNOWN"]},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Additional calendar code for settlement holidays (e.g., USNY for cross-currency pairs)","example":"USNY"},"spotLagDays":{"maximum":2,"minimum":1,"type":"integer","description":"FX spot settlement lag in business days (T+N). 2 for most pairs; 1 for USD T+1 pairs such as USDCAD, USDTRY, USDPHP, USDRUB. Drives value/settlement date derivation.","format":"int32","example":2},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"guardEnabled":{"type":"boolean","description":"Whether CurrencyGuard sells Guards on this pair. A commercial decision, separate from is_active (live rates wanted) and from whether the pair can be priced (a vol surface route with a spread multiplier). New pairs default to false so offering one is deliberate.","example":true}},"description":"Schema for representing a CurrencyPair"},"CurrencyDTOUpdate":{"type":"object","properties":{"code":{"pattern":"^[A-Z]{3}$","type":"string","description":"ISO 4217 currency code","example":"GBP"},"description":{"maxLength":100,"minLength":10,"type":"string","description":"Description of the currency","example":"British Pound Sterling"},"precision":{"maximum":3,"minimum":0,"type":"integer","description":"Precision of the currency (number of decimal places)","format":"int32","example":2},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"isActive":{"type":"boolean","description":"Whether this currency is active. Tombstone flag: false = soft-deleted.","example":true},"rateRoute":{"type":"string","description":"How this currency's discount factors are obtained: DIRECT from a bought curve, or FX_IMPLIED from the USD curve and forward points.","example":"DIRECT","enum":["DIRECT","FX_IMPLIED"]}},"description":"Schema for representing a Currency"},"CurrencyDTO":{"type":"object","properties":{"code":{"pattern":"^[A-Z]{3}$","type":"string","description":"ISO 4217 currency code","example":"GBP"},"description":{"maxLength":100,"minLength":10,"type":"string","description":"Description of the currency","example":"British Pound Sterling"},"precision":{"maximum":3,"minimum":0,"type":"integer","description":"Precision of the currency (number of decimal places)","format":"int32","example":2},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"isActive":{"type":"boolean","description":"Whether this currency is active. Tombstone flag: false = soft-deleted.","example":true},"rateRoute":{"type":"string","description":"How this currency's discount factors are obtained: DIRECT from a bought curve, or FX_IMPLIED from the USD curve and forward points.","example":"DIRECT","enum":["DIRECT","FX_IMPLIED"]},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Currency"},"CounterpartyDTOUpdate":{"type":"object","properties":{"id":{"type":"string","description":"ID for this counterparty","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"counterpartyType":{"type":"string","description":"Type of counterparty: REGULATED_ENTITY, BROKER, PAYMENT_PROVIDER, BANK","example":"BROKER"},"name":{"maxLength":255,"minLength":1,"type":"string","description":"Name of the counterparty (e.g., a liquidity provider or bank)","example":"Example Bank"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID (only for counterparty_type = REGULATED_ENTITY)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Updated counterparty data"},"CounterpartyDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this counterparty","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"counterpartyType":{"type":"string","description":"Type of counterparty: REGULATED_ENTITY, BROKER, PAYMENT_PROVIDER, BANK","example":"BROKER"},"name":{"maxLength":255,"minLength":1,"type":"string","description":"Name of the counterparty (e.g., a liquidity provider or bank)","example":"Example Bank"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID (only for counterparty_type = REGULATED_ENTITY)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Counterparty"},"CalendarDTOUpdate":{"type":"object","properties":{"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"description":{"pattern":"^[A-Z]{4}$","type":"string","description":"Calendar description","example":"TARGET2/Eurozone  "},"isoCountryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 country code","example":"GB or TARGET2"},"isSundayWeekend":{"type":"boolean","description":"Indicates if Sunday is a weekend for this calendar","example":true},"isMondayWeekend":{"type":"boolean","description":"Indicates if Monday is a weekend for this calendar","example":false},"isTuesdayWeekend":{"type":"boolean","description":"Indicates if Tuesday is a weekend for this calendar","example":false},"isWednesdayWeekend":{"type":"boolean","description":"Indicates if Wednesday is a weekend for this calendar","example":false},"isThursdayWeekend":{"type":"boolean","description":"Indicates if Thursday is a weekend for this calendar","example":false},"isFridayWeekend":{"type":"boolean","description":"Indicates if Friday is a weekend for this calendar","example":false},"isSaturdayWeekend":{"type":"boolean","description":"Indicates if Saturday is a weekend for this calendar","example":true}},"description":"Schema for representing a Calendar"},"CalendarDTO":{"type":"object","properties":{"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"description":{"pattern":"^[A-Z]{4}$","type":"string","description":"Calendar description","example":"TARGET2/Eurozone  "},"isoCountryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 country code","example":"GB or TARGET2"},"isSundayWeekend":{"type":"boolean","description":"Indicates if Sunday is a weekend for this calendar","example":true},"isMondayWeekend":{"type":"boolean","description":"Indicates if Monday is a weekend for this calendar","example":false},"isTuesdayWeekend":{"type":"boolean","description":"Indicates if Tuesday is a weekend for this calendar","example":false},"isWednesdayWeekend":{"type":"boolean","description":"Indicates if Wednesday is a weekend for this calendar","example":false},"isThursdayWeekend":{"type":"boolean","description":"Indicates if Thursday is a weekend for this calendar","example":false},"isFridayWeekend":{"type":"boolean","description":"Indicates if Friday is a weekend for this calendar","example":false},"isSaturdayWeekend":{"type":"boolean","description":"Indicates if Saturday is a weekend for this calendar","example":true},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Calendar"},"CalendarDateDTOUpdate":{"type":"object","properties":{"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"nonBusinessDate":{"type":"string","description":"Non business date for the calendar code","example":"2025-01-06"},"description":{"type":"string","description":"Non business date description","example":"Swiss National Day"}},"description":"Schema for representing a CalendarDate"},"CalendarDateDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this calendar date","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"nonBusinessDate":{"type":"string","description":"Non business date for the calendar code","example":"2025-01-06"},"description":{"type":"string","description":"Non business date description","example":"Swiss National Day"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a CalendarDate"},"AccountDTOUpdate":{"type":"object","properties":{"accountCode":{"pattern":"^[0-9]{4}$","type":"string","description":"Account code (e.g., 1010, 4100) - Format: 1xxx=Assets, 2xxx=Liabilities, 3xxx=Equity, 4xxx=Revenue, 5xxx=Expenses","example":"1010"},"accountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"description":{"type":"string","description":"Description of the account","example":"Barclays bank account holding GBP cash"},"accountType":{"type":"string","description":"Account type: ASSET, LIABILITY, EQUITY, REVENUE, or EXPENSE","example":"ASSET"},"accountCategory":{"type":"string","description":"Account category (sub-classification)","example":"CASH"},"normalBalance":{"type":"string","description":"Normal balance side: DEBIT or CREDIT","example":"DEBIT"},"currency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code (GBP, EUR, USD) for fixed-currency accounts (balance sheet), or NULL for native-currency accounts (P&L). NULL means the account accepts postings in any currency.","example":"GBP"},"isActive":{"type":"boolean","description":"Whether this account is active","example":true},"counterpartyId":{"type":"string","description":"Optional counterparty associated with this account (broker, regulated entity, payment provider, etc.)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"}},"description":"Schema for representing a Account"},"AccountDTO":{"type":"object","properties":{"accountCode":{"pattern":"^[0-9]{4}$","type":"string","description":"Account code (e.g., 1010, 4100) - Format: 1xxx=Assets, 2xxx=Liabilities, 3xxx=Equity, 4xxx=Revenue, 5xxx=Expenses","example":"1010"},"accountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"description":{"type":"string","description":"Description of the account","example":"Barclays bank account holding GBP cash"},"accountType":{"type":"string","description":"Account type: ASSET, LIABILITY, EQUITY, REVENUE, or EXPENSE","example":"ASSET"},"accountCategory":{"type":"string","description":"Account category (sub-classification)","example":"CASH"},"normalBalance":{"type":"string","description":"Normal balance side: DEBIT or CREDIT","example":"DEBIT"},"currency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code (GBP, EUR, USD) for fixed-currency accounts (balance sheet), or NULL for native-currency accounts (P&L). NULL means the account accepts postings in any currency.","example":"GBP"},"isActive":{"type":"boolean","description":"Whether this account is active","example":true},"isSystemAccount":{"type":"boolean","description":"Whether this is a system account (protected from deletion)","example":true},"counterpartyId":{"type":"string","description":"Optional counterparty associated with this account (broker, regulated entity, payment provider, etc.)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"counterpartyName":{"maxLength":255,"minLength":1,"type":"string","description":"Name of the counterparty","example":"Saxo Bank A/S"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Account"},"AccountPeriodDTOUpdate":{"type":"object","properties":{"periodName":{"maxLength":50,"minLength":1,"type":"string","description":"Name of the account period","example":"Jan 2026"},"closeStepStatus":{"type":"string","description":"Current step in month-end close process","example":"STEP_2_FX_REVALUATION"},"closeStepProcessingMessage":{"type":"string","description":"Processing message or error from current close step","example":"Missing EOD rate for GBPUSD on 2025-12-31"},"periodStartDate":{"type":"string","description":"Start date of this accounting period (inclusive). Journal entries with value_date >= this date belong to this period.","example":"2026-01-01"},"periodEndDate":{"type":"string","description":"End date of this accounting period (inclusive). NULL means the period is open-ended. Journal entries with value_date <= this date belong to this period.","example":"2026-01-31"}},"description":"Schema for representing a AccountPeriod"},"AccountPeriodDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this account period","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"periodName":{"maxLength":50,"minLength":1,"type":"string","description":"Name of the account period","example":"Jan 2026"},"closeStepStatus":{"type":"string","description":"Current step in month-end close process","example":"STEP_2_FX_REVALUATION"},"closeStepProcessingMessage":{"type":"string","description":"Processing message or error from current close step","example":"Missing EOD rate for GBPUSD on 2025-12-31"},"periodStartDate":{"type":"string","description":"Start date of this accounting period (inclusive). Journal entries with value_date >= this date belong to this period.","example":"2026-01-01"},"periodEndDate":{"type":"string","description":"End date of this accounting period (inclusive). NULL means the period is open-ended. Journal entries with value_date <= this date belong to this period.","example":"2026-01-31"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a AccountPeriod"},"SubscriptionKey":{"type":"object","properties":{"messageType":{"type":"string","enum":["FX_PRICE","MARKET_DATA","GUARDS","FX_OPTIONS","GUARD_PRICE","GUARD_PERFORMANCE","CLOCK","CLOCK_DATE_ROLL","GUARD_QUOTES","FX_VOL_SURFACE","ZERO_RATE_CURVE","PORTFOLIO_VALUATIONS","PORTFOLIO_RISK","FX_FORWARD_CURVE","FX_POSITION_PNL_VALUATION","MARKET_STATUS"]}},"discriminator":{"propertyName":"messageType","mapping":{"FX_PRICE":"#/components/schemas/SubscriptionKeyFX_PRICE","FX_FORWARD_CURVE":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE","MARKET_DATA":"#/components/schemas/SubscriptionKeyMARKET_DATA","GUARD_PRICE":"#/components/schemas/SubscriptionKeyGUARD_PRICE","GUARD_PERFORMANCE":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE","GUARD_QUOTES":"#/components/schemas/SubscriptionKeyGUARD_QUOTES","GUARDS":"#/components/schemas/SubscriptionKeyGUARDS","FX_OPTIONS":"#/components/schemas/SubscriptionKeyFX_OPTIONS","CLOCK":"#/components/schemas/SubscriptionKeyCLOCK","CLOCK_DATE_ROLL":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL","FX_VOL_SURFACE":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE","ZERO_RATE_CURVE":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE","PORTFOLIO_VALUATIONS":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS","PORTFOLIO_RISK":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK","FX_POSITION_PNL_VALUATION":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION","MARKET_STATUS":"#/components/schemas/SubscriptionKeyMARKET_STATUS"}}},"SubscriptionKeyCLOCK":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"frequency":{"type":"number","format":"double"}}}]},"SubscriptionKeyCLOCK_DATE_ROLL":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyFX_FORWARD_CURVE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"currencyPair":{"type":"string"},"forwardCurveSource":{"type":"string"}}}]},"SubscriptionKeyFX_OPTIONS":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyFX_POSITION_PNL_VALUATION":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyFX_PRICE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"currencyPair":{"type":"string"},"source":{"type":"string"},"amount":{"type":"number"}}}]},"SubscriptionKeyFX_VOL_SURFACE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"currencyPair":{"type":"string"},"volSurfaceSource":{"type":"string"}}}]},"SubscriptionKeyGUARDS":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyGUARD_PERFORMANCE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"guardId":{"type":"string"}}}]},"SubscriptionKeyGUARD_PRICE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"guardId":{"type":"string"}}}]},"SubscriptionKeyGUARD_QUOTES":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyMARKET_DATA":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"currencyPair":{"type":"string"}}}]},"SubscriptionKeyMARKET_STATUS":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyPORTFOLIO_RISK":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyPORTFOLIO_VALUATIONS":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"}]},"SubscriptionKeyZERO_RATE_CURVE":{"type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionKey"},{"type":"object","properties":{"currencyCode":{"type":"string"},"irCurveSource":{"type":"string"}}}]},"AcceptInvitationRequestDTO":{"required":["token"],"type":"object","properties":{"token":{"type":"string","description":"The unique invitation token from the email link","example":"abc123xyz456"},"password":{"type":"string","description":"Optional password for headless acceptance (CLI/seed). When provided and allow-headless-password is enabled, the server sets this password directly instead of returning a challenge session. Omit for browser-based acceptance."}},"description":"Request to accept an invitation"},"AcceptInvitationResponseDTO":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates whether the operation was successful","example":true},"userPool":{"type":"string","description":"The user pool/realm the user belongs to","example":"regulated","enum":["internal","regulated","customer"]},"message":{"type":"string","description":"Success message","example":"User created successfully"},"challengeSession":{"type":"string","description":"Cognito challenge session for MiniStack password flow (null for OIDC)"},"email":{"type":"string","description":"User email for MiniStack challenge flow (null for OIDC)"}},"description":"Response after successfully accepting an invitation"},"ChatMessage":{"required":["role"],"type":"object","properties":{"role":{"type":"string"},"content":{"maxLength":2000,"minLength":0,"type":"string"}}},"McpGuardChatRequestDTO":{"required":["messages"],"type":"object","properties":{"messages":{"maxItems":20,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"sessionId":{"type":"string"}}},"McpGuardChatResponseDTO":{"type":"object","properties":{"role":{"type":"string"},"content":{"type":"string"},"toolsUsed":{"type":"array","items":{"type":"string"}}}},"InvitationDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this invitation.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"inviterUserId":{"type":"string","description":"The ID of the user who sent this invitation.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"inviterUserPiiData":{"$ref":"#/components/schemas/InvitationDTOInviterUserPiiData"},"inviteeUserId":{"type":"string","description":"The ID of the user created for this invitation (email stored in PII). Null for new invitations until acceptance.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440005"},"inviteeUserPiiData":{"$ref":"#/components/schemas/InvitationDTOInviteeUserPiiData"},"userType":{"type":"string","description":"The type of user being invited.","example":"REGULATED","enum":["INTERNAL","REGULATED","CUSTOMER"]},"entitlementsTemplateId":{"type":"string","description":"The entitlements template ID to assign to the invited user.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"entitlementsTemplateTemplateName":{"type":"string","description":"The unique name of the entitlements template.","example":"Super User"},"regulatedEntityId":{"type":"string","description":"The regulated entity ID (for sales users and customers).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440002"},"companyId":{"type":"string","description":"The company ID (for customer users only).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440003"},"invitationToken":{"maxLength":500,"minLength":0,"type":"string","description":"The unique invitation token for validation.","example":"eyJhbGciOiJIUzI1NiJ9..."},"status":{"type":"string","description":"The current status of the invitation.","example":"PENDING","enum":["PENDING","COMPLETED","EXPIRED","REVOKED"]},"expiresAt":{"type":"string","description":"When the invitation expires in UTC.","example":"2024-10-25T12:30:40Z"},"completedAt":{"type":"string","description":"When the invitation was completed in UTC.","example":"2024-10-20T14:15:30Z"},"piiData":{"$ref":"#/components/schemas/InvitationDTOPiiData"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"introducingBrokerId":{"type":"string","description":"The introducing broker ID (for sales user invitations).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440006"},"createdUserId":{"type":"string","description":"DEPRECATED: Use invitee_user_id instead. The ID of the user created after successful onboarding.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440004"},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Invitation"},"CreateRegulatedUserInvitationByRegulatedUserDTO":{"required":["email","firstName","lastName"],"type":"object","properties":{"email":{"maxLength":100,"minLength":0,"type":"string","description":"Email address of the person being invited","example":"jane.doe@salesteam.com"},"firstName":{"maxLength":50,"minLength":0,"type":"string","description":"First name of the person being invited","example":"Jane"},"lastName":{"maxLength":50,"minLength":0,"type":"string","description":"Last name of the person being invited","example":"Doe"},"message":{"maxLength":2000,"minLength":0,"type":"string","description":"Optional welcome message for the invitation","example":"Welcome to our sales team! Please complete your onboarding."},"entitlementsTemplateName":{"maxLength":100,"minLength":0,"type":"string","description":"Entitlements template name to assign to the invited user","example":"Regulated User"}},"description":"Request to create a regulated user invitation within the same regulated entity"},"CreateCustomerInvitationBySalesUserDTO":{"required":["companyId","email","firstName","lastName"],"type":"object","properties":{"email":{"maxLength":100,"minLength":0,"type":"string","description":"Email address of the person being invited","example":"john.smith@company.com"},"firstName":{"maxLength":50,"minLength":0,"type":"string","description":"First name of the person being invited","example":"John"},"lastName":{"maxLength":50,"minLength":0,"type":"string","description":"Last name of the person being invited","example":"Smith"},"companyId":{"type":"string","description":"The company ID the customer user will belong to","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"message":{"maxLength":2000,"minLength":0,"type":"string","description":"Optional welcome message for the invitation","example":"Welcome to your company account! Please complete your onboarding."},"entitlementsTemplateName":{"maxLength":100,"minLength":0,"type":"string","description":"Entitlements template name to assign to the invited user","example":"Self Service Customer"}},"description":"Request to create a customer user invitation"},"SettleGuardRequestDTO":{"required":["clientConversionAmount","conversionRate","foreignAmount","foreignCurrency","guardCurrency"],"type":"object","properties":{"foreignAmount":{"type":"number"},"foreignCurrency":{"type":"string"},"guardCurrency":{"type":"string"},"conversionRate":{"type":"number"},"clientConversionAmount":{"type":"number","description":"What this tranche would cost the client at their own all-in rate. Required on every settlement."},"customerId":{"type":"string","format":"uuid"}}},"GuardSettlementDTO":{"type":"object","properties":{"id":{"type":"string","description":"Reference for this settlement, appended to the Guard generation it settled.","example":"GSP1000104-E01-S02"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard settlement (denormalized from guard)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedUserId":{"type":"string","description":"ID of the regulated user who booked this guard settlement","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"salesUserId":{"type":"string","description":"ID of the sales user who sold this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this payment","format":"uuid"},"customerId":{"type":"string","description":"ID of the customer who owns this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"settlementDate":{"type":"string","description":"Settlement date of this guard settlement, when the FX conversion occurs","example":"2024-04-09"},"paymentDate":{"type":"string","description":"Payment date, calculated as settlement_date + 2 business days. The date when funds are actually transferred","example":"2024-04-11"},"guardPeriodFrom":{"type":"string","description":"Start period date of this guard, also the purchase date","example":"2024-01-16"},"guardFeeDate":{"type":"string","description":"Guard fee payment date, calculated as guard_period_from + 2 business days. Corresponds to the premium payment date on the back-to-back hedge.","example":"2024-01-18"},"settlementWindowFrom":{"type":"string","description":"Start settlement window of this guard, typically two weeks due date of the final payment","example":"2024-01-16"},"settlementWindowTo":{"type":"string","description":"End settlement window of this guard, typically the due date of the final payment","example":"2024-04-15"},"guardPeriodTo":{"type":"string","description":"End period date of this guard, typically one day after the due date of the final payment","example":"2024-04-15"},"guardPeriodToValueDate":{"type":"string","description":"Settlement date of the guard, calculated as guard_period_to + 2 business days. Must match the settlement date on the back-to-back hedge.","example":"2024-04-17"},"guardSettlementStatus":{"pattern":"^(AWAITING_FUNDING|EXECUTION_PENDING|FUNDING_LAPSED|FUNDING_CANCELLED|SETTLEMENT_PENDING|SETTLEMENT_EXECUTED|SETTLEMENT_REJECTED|EXTENSION_PENDING|EXTENSION_EXECUTED|CANCELLATION_PENDING|CANCELLATION_EXECUTED|VOID_EXECUTED)$","type":"string","description":"Status of this settlement","example":"SETTLEMENT_EXECUTED","enum":["AWAITING_FUNDING","EXECUTION_PENDING","FUNDING_LAPSED","FUNDING_CANCELLED","SETTLEMENT_PENDING","SETTLEMENT_EXECUTED","SETTLEMENT_REJECTED","EXTENSION_PENDING","EXTENSION_EXECUTED","CANCELLATION_PENDING","CANCELLATION_EXECUTED","VOID_EXECUTED"]},"batchId":{"maxLength":10,"minLength":0,"type":"string","description":"Settlement batch this row was requested as part of, if any","example":"BSP0000042"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the settlement is for the payment or receipt of foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Guard currency, the currency in which the cost or receivable is being protected.","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of the settlement, matches the invoice or bill currency","example":"EUR"},"foreignAmount":{"type":"number","description":"Foreign amount the customer paid or received in the foreign currency for this settlement","example":75000},"guardRate":{"type":"number","description":"Guard rate from the original guard contract","example":1.1405},"guardAmount":{"type":"number","description":"Protected amount in guard currency - what the customer is guaranteed to receive/pay at the guard rate (foreign_amount ÷ guard_rate)","example":65760.63},"deliveredAmount":{"type":"number","description":"Amount CGL delivers to the client at settlement, in delivered_currency. Pay: the invoice in foreign currency. Receive: the floor or the all-in in guard currency.","example":100000},"deliveredCurrency":{"type":"string","description":"Currency of delivered_amount. Guard-Pay: foreign currency. Guard-Receive: guard currency.","example":"GBP"},"shortfallAmount":{"type":"number","description":"Amount the guard pays out when market moves unfavorably. For Guard-Receive: in guard currency (guard_amount - conversion_amount). For Guard-Pay: in foreign currency (foreign_amount × (guard_rate - conversion_rate) / guard_rate). Zero or positive when guard provides protection.","example":2147.4},"shortfallCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency of the shortfall amount. Guard-Receive: guard currency. Guard-Pay: foreign currency.","example":"GBP"},"savingsRebateAmount":{"type":"number","description":"Savings-zone rebate owed to the client on a funded settlement, in the funding currency","example":1660.12},"savingsRebateCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency of the savings rebate","example":"USD"},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time of settlement","example":1.17895},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time of settlement","example":1.17905},"conversionRate":{"type":"number","description":"Actual market FX rate at settlement time used for the conversion","example":1.179},"conversionAmount":{"type":"number","description":"What the tranche costs/yields the client at their own all-in rate (mid plus the declared payment margin). Above the guard amount means the Guard is protecting.","example":139055},"executedConversionRate":{"type":"number","description":"The rate CGL actually converted at with the regulated entity at execution, versus conversion_rate which is the mid.","example":1.3670475},"conversionProceeds":{"type":"number","description":"Proceeds CGL received from the execution conversion, in the bought currency.","example":99491.79},"reFxMarginAmount":{"type":"number","description":"The regulated entity's FX margin earned on CGL's execution conversion, in guard currency. Feeds the month-end true-up.","example":203.76},"declaredMarginPct":{"type":"number","description":"Client payment margin declared at settlement, as a decimal (0.016 = 1.6%)","example":0.016},"trueUpAmount":{"type":"number","description":"Signed CGL/RE margin true-up in the guard currency. Positive means the regulated entity owes CurrencyGuard; negative means CurrencyGuard owes the regulated entity.","example":685},"settlementZone":{"pattern":"^(PROTECTION|SAVINGS|NOT_APPLICABLE|UNKNOWN)$","type":"string","description":"Whether the Guard paid out on this tranche. PROTECTION: the client's own cost is above the cap, CGL funds the shortfall. SAVINGS: it is below, the client settles at market and CGL is not involved. NOT_APPLICABLE: a cancellation or void, where nothing was converted.","example":"PROTECTION","enum":["PROTECTION","SAVINGS","NOT_APPLICABLE","UNKNOWN"]},"refundAmount":{"type":"number","description":"Refund amount returned to client for guard cancellation in guard currency. Only populated for cancellation settlements.","example":334},"refundCalculation":{"$ref":"#/components/schemas/GuardSettlementDTORefundCalculation"},"salesMarginAmount":{"type":"number","description":"Sales margin amount applied to the conversion rate as a rate (e.g. 0.01 = 1%). Positive means sales took margin, negative means customer got better than market rate.","example":0.0025},"totalForeignAmountSettled":{"type":"number","description":"Total foreign amount settled on the guard BEFORE this settlement (cumulative from previous settlements)","example":20000},"totalGuardAmountSettled":{"type":"number","description":"Total guard amount settled on the guard BEFORE this settlement (cumulative from previous settlements)","example":15243.9},"guardId":{"type":"string","description":"ID of the guard associated with this payment","example":"1b6453892-e5e1-4fad-9e9b-4fa4e60f6c2b"},"originalGuardId":{"type":"string","description":"ID of the original guard at the start of the lifecycle. Remains constant through extensions and other lifecycle changes.","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"creditorReference":{"type":"string","description":"RF creditor reference to quote when funding this settlement","example":"RF13GIX0000001S01"},"fundingCurrency":{"type":"string","description":"Currency the client sends to fund this settlement","example":"USD"},"fundingAmount":{"type":"number","description":"Amount the client sends to fund this settlement","example":20000}},"description":"Schema for representing a GuardSettlement"},"SalesRequestFundedSettlement":{"required":["foreignAmount"],"type":"object","properties":{"foreignAmount":{"type":"number"},"customerId":{"type":"string","format":"uuid"}}},"GuardExtensionQuoteRequestDTO":{"required":["extendToDate"],"type":"object","properties":{"extendToDate":{"type":"string","description":"New end date for the guard extension in ISO 8601 format","example":"2024-12-31T23:59:59Z"},"reason":{"type":"string","description":"Reason for the guard extension","example":"Contract renewal"},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMarginAmount is calculated. If only salesMarginAmount is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request. If neither provided, defaults to zero.","example":0.007},"salesMarginAmount":{"type":"number","description":"Sales margin amount in guard currency. If only salesMarginAmount is provided, salesMarginRate is calculated. If only salesMarginRate is provided, salesMarginAmount is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request. If neither provided, defaults to zero.","example":350},"customerId":{"type":"string","description":"Customer ID (optional). If not provided, inherits customer from original guard. Allows changing customer during extension.","example":"123e4567-e89b-12d3-a456-426614174000"}},"description":"Request data for calculating a guard extension quote"},"GuardQuoteStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/InternalGuardQuoteDTO"}},"description":"Container for guard quote data with state information. The 'value' field contains quote details and can be present even when valid=false (stale/approximate data)."},"InternalGuardQuoteDTO":{"required":["companyId","foreignCurrency","guardCurrency","guardSettlementWindowTo","midAtInception","payReceive"],"type":"object","properties":{"id":{"type":"string","description":"ID for this guard quote","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard quote (denormalized from company)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedUserId":{"type":"string","description":"ID of the regulated user who created this quote","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"salesUserId":{"type":"string","description":"ID of the sales user on whose behalf this quote is being created. Must belong to an introducing broker within the regulated entity.","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"customerId":{"type":"string","description":"ID of the customer who requested this quote","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"validationStatus":{"pattern":"^(VALID|ERROR)$","type":"string","description":"Validation status of the market data used to price this quote","example":"VALID","enum":["VALID","ERROR"]},"validationErrors":{"maxLength":1000,"minLength":0,"type":"string","description":"Validation error messages if market data was stale or invalid when quote was priced. Semicolon-separated list of errors.","example":"FX vol surface exceeded TTL; Interest rate curve is stale"},"quoteStatus":{"pattern":"^(OPEN|TRADED)$","type":"string","description":"Lifecycle status of the quote","example":"OPEN","enum":["OPEN","TRADED"]},"marketStatus":{"pattern":"^(OPEN|CLOSED)$","type":"string","description":"Market status at the time the quote was generated","example":"OPEN","enum":["OPEN","CLOSED"]},"marketReason":{"maxLength":100,"minLength":0,"type":"string","description":"Reason for the market status at the time the quote was generated","example":"Trading hours"},"previousGuardId":{"type":"string","description":"Id of the Guard being extended by this quote","example":"GSP1000104"},"externalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference for the guard quote. Could be the beneficiary identifier or a foreign key in the PSP platform. Avoid using Personally Identifiable Information in this field.","example":"BEN-90210"},"invoiceExternalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference of the customer invoice this guard quote protects. Carried onto the guard when the quote is purchased. Avoid using Personally Identifiable Information in this field.","example":"INV-2024-001"},"guardPeriodFrom":{"type":"string","description":"Start period date of this guard, also the purchase date","example":"2024-01-16"},"settlementWindowFrom":{"type":"string","description":"Start settlement window of this guard, typically two weeks due date of the final payment","example":"2024-01-16"},"settlementWindowTo":{"type":"string","description":"End settlement window of this guard, typically the due date of the final payment","example":"2024-04-15"},"guardPeriodTo":{"type":"string","description":"End period date of this guard, typically one day after the due date of the final payment","example":"2024-04-15"},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The Guard currency is the currency in which the cost or receivable is being protected typically the corporate base currency","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of this guard, matching the invoice or bill currency","example":"USD"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"The traded currency pair this guard is booked on, in CurrencyPair convention. The guard currency may be either leg of this pair.","example":"GBPUSD"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":50000},"guardRate":{"type":"number","description":"Guard rate of exchange","example":1.312},"paymentMarginAtInception":{"type":"number","description":"Client payment margin inside the guard rate, as a decimal (0.015 = 1.5%). 0 = the guard rate is CGL's mid.","example":0.015},"midAtInception":{"type":"number","description":"The market mid the caller observed and priced against. Checked against CurrencyGuard's own feed; a mid outside tolerance is refused.","example":1.34},"quoteTimeToLiveInSeconds":{"type":"integer","description":"Time to live for the quote in seconds","format":"int32","example":60},"guardAmount":{"type":"number","description":"GuardQuote amount in the guard currency, derived from the foreign amount and guard rate","example":38109.75},"guardFee":{"type":"number","description":"Fee paid for the guard in the guard currency","example":512},"effectiveRate":{"type":"number","description":"Net rate to client after costs","example":1.2946},"payLaterCreditFee":{"type":"number","description":"Pay later Credit Fee paid for the guard in the guard currency. This fee is calculated when payLater=true is specified in the quote request, otherwise defaults to 0.00","example":12},"guardMarginRate":{"type":"number","description":"GuardQuote margin rate as a percentage","example":0.007},"guardMargin":{"type":"number","description":"GuardQuote margin amount incorporated into the guard fee and expressed in guard currency","example":296.02},"volSpreadMultiplier":{"type":"number","description":"Vol spread multiplier applied to the market vol bid/ask when this quote was priced. 1.0 = unadjusted market spread.","example":2},"valuationStrike":{"type":"number","description":"Valuation rate this quote was priced against: the mid rounded to 0.0005 in CGL's favour","example":1.34},"valuationNotional":{"type":"number","description":"Valuation notional in the foreign currency: guard amount divided by the valuation rate","example":101500},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMargin amount is calculated. If only salesMargin is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":0.007},"salesMargin":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency. If only salesMargin is provided, salesMarginRate is calculated. If only salesMarginRate is provided, salesMargin amount is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":296.02},"priceExplain":{"maxLength":50000,"minLength":0,"type":"string","description":"Price explain for this guard - this is used for internal testing only and will be removed from the API in future releases."},"quoteTimestamp":{"type":"string","description":"Timestamp when the quote was generated","example":"2024-10-18T12:30:40Z"},"spotBidPrice":{"type":"number","description":"Spot bid price for FX at time of quote","example":1.2345},"spotAskPrice":{"type":"number","description":"Spot ask price for FX at time of quote","example":1.2347},"historicVolatility":{"type":"number","description":"Historic volatility used in pricing calculation","example":0.1234},"riskIndex":{"type":"number","description":"Risk index calculated for this quote","example":0.5678},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"guardSettlementWindowTo":{"type":"string","description":"End settlement window of this guard in ISO 8601 format, typically the due date of the final payment","example":"2024-04-15T00:00:00Z"},"targetGuardAmountToSeekNetFees":{"type":"number","description":"Amount of the guard in the guard currency to seek for net of fees","example":60000},"salesMarginAmount":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency","example":296.02},"reason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the guard quote request","example":"Invoice protection for Q1 2024"},"payLater":{"type":"boolean","description":"Flag indicating whether fees should be paid later. Defaults to false if not specified.","example":false},"requestedGuardAmount":{"type":"number","description":"The funding requirement in the guard currency: the cap (Guard-Pay) or floor (Guard-Receive) the client is protected to, before fees. This is the client's own all-in price for the invoice, so the payment margin and the guard rate are DERIVED from it rather than sent -- amounts are exact to the cent, rates are 5dp roundings. Absent: CGL prices off its own mid with no payment margin, which is the pre-client-rate behaviour.","example":136010}},"description":"Schema for representing a GuardQuote"},"SalesCancelFundingRequest":{"type":"object","properties":{"reason":{"type":"string"}}},"CancelGuardRequestDTO":{"required":["salesMarginAmount"],"type":"object","properties":{"salesMarginAmount":{"type":"number","description":"Sales margin adjustment in guard currency. Positive values reduce the refund (PSP retains margin); negative values increase it (PSP adds to refund).","example":50},"reason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for cancelling the guard (optional)","example":"Client requested cancellation due to contract termination"}},"description":"Request to cancel a guard with optional sales margin"},"CancelGuardResponseDTO":{"type":"object","properties":{"guard":{"$ref":"#/components/schemas/GuardDTO"},"refundAmount":{"type":"number","description":"Refund amount returned to the client in guard currency (after deducting sales margin)","example":334},"salesMarginAmount":{"type":"number","description":"Sales margin charged to the client","example":50},"settlementId":{"type":"string","description":"ID of the guard settlement record created for this cancellation","example":"e1f2d3c4-b5a6-7890-9c8d-7e6f5d4c3b2a"},"guardCurrency":{"type":"string","description":"Guard currency code","example":"GBP"}},"description":"Guard cancellation response with refund details"},"GuardDTO":{"type":"object","properties":{"id":{"type":"string","description":"Reference for this guard. The original is bare; extensions carry an -E{nn} suffix.","example":"GSP1000104"},"originalGuardId":{"type":"string","description":"Id of the original Guard at the start of the lifecycle. Constant through extensions.","example":"GSP1000104"},"previousGuardId":{"type":"string","description":"Id of the Guard generation this one extended. NULL on an original.","example":"GSP1000104"},"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard (denormalized from company)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedUserId":{"type":"string","description":"ID of the regulated user who booked this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"salesUserId":{"type":"string","description":"ID of the sales user who sold this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"customerId":{"type":"string","description":"ID of the customer who owns this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"guardStatus":{"type":"string","description":"Status of this guard","example":"ACTIVE","enum":["ERROR","CANCELLED","PENDING","AWAITING_FEE","ACTIVE","COMPLETE","LAPSED","VOID","EXTENDED"]},"externalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference for the guard. Could be the beneficiary identifier or a foreign key in the PSP platform. Avoid using Personally Identifiable Information in this field.","example":"BEN-90210"},"invoiceExternalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference of the customer invoice this guard protects. Copied from the guard quote at purchase. Avoid using Personally Identifiable Information in this field.","example":"INV-2024-001"},"guardPeriodFrom":{"type":"string","description":"Start period date of this guard, also the purchase date","example":"2024-01-16"},"tradeDate":{"type":"string","description":"Trade date for this guard. The actual transaction datetime when the guard was created or extended.","example":"2024-01-16T11:00:00Z"},"settlementWindowFrom":{"type":"string","description":"Start settlement window of this guard, typically two weeks due date of the final payment","example":"2024-01-16"},"settlementWindowTo":{"type":"string","description":"End settlement window of this guard, typically the due date of the final payment","example":"2024-04-15"},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The Guard currency is the currency in which the cost or receivable is being protected typically the corporate base currency","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of this guard, matching the invoice or bill currency","example":"USD"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"The traded currency pair this guard is booked on, in CurrencyPair convention. The guard currency may be either leg of this pair.","example":"GBPUSD"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":50000},"totalForeignAmountSettled":{"type":"number","description":"Total foreign amount settled so far in the foreign currency","example":15000},"guardRate":{"type":"number","description":"Guard rate of exchange","example":1.3121},"paymentMarginAtInception":{"type":"number","description":"Client payment margin inside the guard rate, frozen at inception, as a decimal (0.015 = 1.5%)","example":0.015},"midAtInception":{"type":"number","description":"CGL market mid the guard rate was derived from, copied from the guard quote","example":1.34},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time the guard was created, copied from the guard quote","example":1.3115},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time the guard was created, copied from the guard quote","example":1.3125},"guardAmount":{"type":"number","description":"Guard amount in the guard currency, derived from the foreign amount and guard rate","example":38109.75},"totalGuardAmountSettled":{"type":"number","description":"Total guard amount settled so far in the guard currency","example":11432.92},"guardFee":{"type":"number","description":"Fee paid for the guard in the guard currency","example":512},"guardFeeDate":{"type":"string","description":"Guard fee payment date, calculated as trade_date + 2 business days. Corresponds to the premium payment date on the back-to-back hedge.","example":"2024-01-18"},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMargin amount is calculated. If only salesMargin is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":0.007},"salesMargin":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency. If only salesMargin is provided, salesMarginRate is calculated. If only salesMarginRate is provided, salesMargin amount is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":296.02},"effectiveRate":{"type":"number","description":"Effective rate to the client after all costs including the Guard fee and margins","example":1.2946},"guardQuoteId":{"type":"string","description":"ID of the guard quote that was used to create this guard","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp when of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"expectedPaymentMargin":{"type":"number","description":"Expected payment margin still to be earned on the unsettled portion of this guard, in guard currency","example":1250.5},"realizedPaymentMargin":{"type":"number","description":"Realized payment margin from SETTLEMENT_EXECUTED settlements to date, net of true-ups, in guard currency","example":875.25}},"description":"Schema for representing a Guard"},"SalesRequestFundedSettlements":{"required":["settlements"],"type":"object","properties":{"settlements":{"type":"array","items":{"$ref":"#/components/schemas/SalesRequestFundedSettlementsLine"}},"customerId":{"type":"string","format":"uuid"}}},"SalesRequestFundedSettlementsLine":{"required":["foreignAmount","guardId"],"type":"object","properties":{"guardId":{"type":"string"},"foreignAmount":{"type":"number"}}},"SmartParseGuardQuoteRequestDTO":{"required":["text"],"type":"object","properties":{"text":{"maxLength":2000,"minLength":0,"type":"string","description":"Natural language text describing the guard transaction","example":"Thames Trading needs to buy €650k against GBP in 45 days for supplier invoice TT-2025-443 with 25 basis points and they want to pay later"}},"description":"Request to parse natural language text into guard quote fields"},"SmartParseGuardQuoteResponseDTO":{"type":"object","properties":{"payReceive":{"type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignCurrency":{"type":"string","description":"Foreign currency of this guard (ISO 4217 code)","example":"EUR"},"guardCurrency":{"type":"string","description":"Guard currency, typically the corporate base currency (ISO 4217 code)","example":"GBP"},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":650000},"targetGuardAmount":{"type":"number","description":"Target amount in guard currency (net of fees) - alternative to foreignAmount","example":735000},"guardSettlementWindowTo":{"type":"string","description":"End settlement window of this guard in ISO 8601 format","example":"2026-01-06T00:00:00Z"},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g., 0.0025 = 25bps = 0.25%)","example":0.0025},"salesMarginAmount":{"type":"number","description":"Sales margin as an absolute amount in guard currency","example":800},"guardMarginRate":{"type":"number","description":"Guard margin rate as a decimal, incorporated into the guard fee (e.g., 0.01 = 1%)","example":0.01},"paymentMarginAtInception":{"type":"number","description":"Payment margin rate inside the guard rate, applied at inception, as a decimal (e.g., 0.01 = 1%)","example":0.01},"externalRef":{"type":"string","description":"External reference such as invoice or contract number","example":"TT-2025-443"},"companyName":{"type":"string","description":"Parsed company name for fuzzy matching","example":"Thames Trading"},"customerName":{"type":"string","description":"Parsed customer contact name","example":"John Smith"},"customerEmail":{"type":"string","description":"Customer email address","example":"john.smith@thamestrading.co.uk"},"isPayLater":{"type":"boolean","description":"Whether pay-later option was requested","example":true},"amountInputMode":{"type":"string","description":"Amount input mode indicating which amount was specified","example":"foreign","enum":["foreign","guard"]},"reason":{"type":"string","description":"Additional context or notes about the guard transaction","example":"Supplier invoice TT-2025-443"}},"description":"Parsed guard quote fields from natural language input"},"SalesGuardQuoteDTO":{"required":["companyId","foreignCurrency","guardCurrency","guardSettlementWindowTo","midAtInception","payReceive"],"type":"object","properties":{"companyId":{"type":"string","description":"ID of the company associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"customerId":{"type":"string","description":"ID of the customer who requested this quote","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"externalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference for the guard quote. Could be the beneficiary identifier or a foreign key in the PSP platform. Avoid using Personally Identifiable Information in this field.","example":"BEN-90210"},"invoiceExternalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference of the customer invoice this guard quote protects. Carried onto the guard when the quote is purchased. Avoid using Personally Identifiable Information in this field.","example":"INV-2024-001"},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The Guard currency is the currency in which the cost or receivable is being protected typically the corporate base currency","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of this guard, matching the invoice or bill currency","example":"USD"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"The traded currency pair this guard is booked on, in CurrencyPair convention. The guard currency may be either leg of this pair.","example":"GBPUSD"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":50000},"paymentMarginAtInception":{"type":"number","description":"Client payment margin inside the guard rate, as a decimal (0.015 = 1.5%). 0 = the guard rate is CGL's mid.","example":0.015},"midAtInception":{"type":"number","description":"The market mid the caller observed and priced against. Checked against CurrencyGuard's own feed; a mid outside tolerance is refused.","example":1.34},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMargin amount is calculated. If only salesMargin is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":0.007},"guardSettlementWindowTo":{"type":"string","description":"End settlement window of this guard in ISO 8601 format, typically the due date of the final payment","example":"2024-04-15T00:00:00Z"},"targetGuardAmountToSeekNetFees":{"type":"number","description":"Amount of the guard in the guard currency to seek for net of fees","example":60000},"salesMarginAmount":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency","example":296.02},"reason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the guard quote request","example":"Invoice protection for Q1 2024"},"payLater":{"type":"boolean","description":"Flag indicating whether fees should be paid later. Defaults to false if not specified.","example":false},"requestedGuardAmount":{"type":"number","description":"The funding requirement in the guard currency: the cap (Guard-Pay) or floor (Guard-Receive) the client is protected to, before fees. This is the client's own all-in price for the invoice, so the payment margin and the guard rate are DERIVED from it rather than sent -- amounts are exact to the cent, rates are 5dp roundings. Absent: CGL prices off its own mid with no payment margin, which is the pre-client-rate behaviour.","example":136010}},"description":"Schema for representing a GuardQuote"},"CompanyDTOCreate":{"type":"object","properties":{"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this company belongs to.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"piiData":{"$ref":"#/components/schemas/CompanyDTOCreatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this company's users authenticate against, shared with its broker.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The company's functional/home currency (ISO 4217). Defaults the guard currency for this company's guards.","example":"GBP"}},"description":"Company data to create"},"UserDTOCreate":{"required":["entitlements","entitlementsTemplateId"],"type":"object","properties":{"subClaim":{"type":"string","description":"The unique identifier from JWT sub claim for this user.","example":"auth0|12345678-1234-4001-8000-123456789012"},"roleClaims":{"maxLength":500,"minLength":0,"type":"string","description":"The role claims for this user as a concatenated string.","example":"ROLE_ADMIN,ROLE_TRADER"},"status":{"type":"string","description":"The status of this user account.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"entitlementsTemplateId":{"type":"string","description":"The entitlements template assigned to this user.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"piiData":{"$ref":"#/components/schemas/UserDTOCreatePiiData"}},"description":"Customer creation data"},"WebhookSubscriptionCreateRequestDTO":{"required":["endpointUrl","subscriptionName"],"type":"object","properties":{"subscriptionName":{"maxLength":100,"minLength":0,"type":"string","description":"Human-readable name for this subscription, unique within your regulated entity","example":"Production order book"},"endpointUrl":{"maxLength":500,"minLength":0,"pattern":"^https://.+","type":"string","description":"HTTPS endpoint to which signed event payloads will be POSTed","example":"https://psp.example.com/webhooks/currencyguard"}},"description":"Request data for registering a webhook subscription"},"WebhookSubscriptionCreatedDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID of the created subscription","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"subscriptionName":{"type":"string","description":"Subscription name","example":"Production order book"},"endpointUrl":{"type":"string","description":"Endpoint URL","example":"https://psp.example.com/webhooks/currencyguard"},"status":{"type":"string","description":"Subscription status","example":"ACTIVE"},"signingSecret":{"type":"string","description":"HMAC-SHA256 signing secret — shown only once. Store it securely; it cannot be retrieved later.","example":"whsec_3J8x...redacted..."},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2026-06-13T12:30:40Z"},"message":{"type":"string","description":"Human-readable note about the one-time secret"}},"description":"Webhook subscription details including the one-time signing secret"},"WebhookSubscriptionReplayRequestDTO":{"type":"object","properties":{"fromSequence":{"type":"integer","description":"First event sequence to redeliver (inclusive). Omit to replay from the beginning.","format":"int64","nullable":true,"example":0}},"description":"Request data for replaying webhook events from a checkpoint"},"WebhookSubscriptionDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this webhook subscription","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"subscriptionName":{"maxLength":100,"minLength":0,"type":"string","description":"Human-readable name for this subscription, unique per regulated entity","example":"Production order book"},"endpointUrl":{"maxLength":500,"minLength":0,"type":"string","description":"HTTPS endpoint to which signed event payloads are POSTed","example":"https://psp.example.com/webhooks/currencyguard"},"status":{"type":"string","description":"Status of this subscription","example":"ACTIVE","enum":["ACTIVE","PAUSED","DISABLED","DELETED"]},"lastEventSequence":{"type":"integer","description":"Highest event sequence number delivered to this subscription. -1 means nothing delivered yet.","format":"int64","example":48201},"lastPushAt":{"type":"string","description":"Timestamp of the most recent delivery attempt in UTC","example":"2026-05-30T14:23:01Z"},"lastPushStatus":{"type":"integer","description":"HTTP status code returned by the most recent delivery attempt","format":"int32","example":200},"lastErrorMessage":{"maxLength":500,"minLength":0,"type":"string","description":"Error message from the most recent failed delivery attempt","example":"Connection timed out after 10s"},"consecutiveFailures":{"type":"integer","description":"Number of consecutive delivery failures. Reset to 0 on success; subscription auto-pauses when the configured threshold is reached.","format":"int32","example":0},"pausedAt":{"type":"string","description":"Timestamp when this subscription was paused (auto or manual) in UTC","example":"2026-05-30T14:23:01Z"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a WebhookSubscription"},"SubscriptionRequest":{"type":"object","properties":{"action":{"type":"string","enum":["SUBSCRIBE","UNSUBSCRIBE"]},"timestamp":{"type":"string"},"subscriptionKey":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionKeyCLOCK"},{"$ref":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL"},{"$ref":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_OPTIONS"},{"$ref":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION"},{"$ref":"#/components/schemas/SubscriptionKeyFX_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARDS"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_QUOTES"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_DATA"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_STATUS"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS"},{"$ref":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE"}]}},"description":"Subscription request for type generation only"},"MessageHeader":{"type":"object","properties":{"timestamp":{"type":"string"},"subscriptionKey":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionKeyCLOCK"},{"$ref":"#/components/schemas/SubscriptionKeyCLOCK_DATE_ROLL"},{"$ref":"#/components/schemas/SubscriptionKeyFX_FORWARD_CURVE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_OPTIONS"},{"$ref":"#/components/schemas/SubscriptionKeyFX_POSITION_PNL_VALUATION"},{"$ref":"#/components/schemas/SubscriptionKeyFX_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyFX_VOL_SURFACE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARDS"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PERFORMANCE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_PRICE"},{"$ref":"#/components/schemas/SubscriptionKeyGUARD_QUOTES"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_DATA"},{"$ref":"#/components/schemas/SubscriptionKeyMARKET_STATUS"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_RISK"},{"$ref":"#/components/schemas/SubscriptionKeyPORTFOLIO_VALUATIONS"},{"$ref":"#/components/schemas/SubscriptionKeyZERO_RATE_CURVE"}]}},"description":"Message header for type generation only"},"MessageEnvelopeObject":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"type":"object"}},"description":"Generic message envelope for type generation only"},"MessageEnvelopeMarketStatusDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/MarketStatusDTO"}}},"MessageEnvelopeGuardDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/GuardDTO"}}},"FXPriceDTO":{"type":"object","properties":{"symbol":{"type":"string","description":"Currency pair symbol.","example":"GBPUSD"},"timestamp":{"type":"string","description":"Timestamp when the price was recorded (ISO 8601 format).","example":"2024-03-01T14:30:15.123Z"},"bid":{"type":"number","description":"Bid price - the rate at which the market will buy the base currency.","example":1.09235},"ask":{"type":"number","description":"Ask price - the rate at which the market will sell the base currency.","example":1.09255},"mid":{"type":"number","description":"Mid price - the average of bid and ask prices","example":1.09245}},"description":"Foreign exchange price data containing bid, ask, and mid rates for a currency pair"},"FXPriceStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXPriceDTO"}},"description":"Container for FX spot price data with state information. The 'value' field contains bid/ask/mid rates and can be present even when valid=false (stale/approximate data).","example":"GBPUSD for EURUSD pair"},"MessageEnvelopeFXPriceStateDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXPriceStateDTO"}}},"MessageEnvelopeFXPriceDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXPriceDTO"}}},"ClockSnapshotDTO":{"type":"object","properties":{"now":{"type":"string","description":"Current timestamp of the clock in ISO 8601 format","example":"2024-10-18T12:30:40Z"},"mode":{"type":"string","description":"Clock mode indicating whether time is real-time or simulated","example":"REAL"},"speed":{"type":"number","description":"Clock speed (0.0 = stopped, 1.0 = normal, 2.0 = double speed)","format":"double","example":1}},"description":"Schema for representing a clock snapshot"},"MessageEnvelopeClockSnapshotDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/ClockSnapshotDTO"}}},"CreateSalesUserInvitationByRegulatedUserDTO":{"required":["email","firstName","introducingBrokerId","lastName"],"type":"object","properties":{"email":{"maxLength":100,"minLength":0,"type":"string","description":"Email address of the person being invited","example":"jane.doe@salesteam.com"},"firstName":{"maxLength":50,"minLength":0,"type":"string","description":"First name of the person being invited","example":"Jane"},"lastName":{"maxLength":50,"minLength":0,"type":"string","description":"Last name of the person being invited","example":"Doe"},"introducingBrokerId":{"type":"string","description":"The introducing broker ID the sales user will belong to","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"message":{"maxLength":2000,"minLength":0,"type":"string","description":"Optional welcome message for the invitation","example":"Welcome to our sales team! Please complete your onboarding."},"entitlementsTemplateName":{"maxLength":100,"minLength":0,"type":"string","description":"Entitlements template name to assign to the invited user","example":"Sales User"}},"description":"Request to create a sales user invitation by a regulated user"},"IntroducingBrokerDTOCreate":{"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this introducing broker belongs to.","format":"uuid","example":"eeeeeeee-ee11-4001-8000-000000000000"},"piiData":{"$ref":"#/components/schemas/IntroducingBrokerDTOCreatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this broker's own staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000002"},"customerOauthPoolId":{"type":"string","description":"The OAuth pool the customers of this broker's companies authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"salesAuthSubdomain":{"type":"string","description":"Optional DNS label for the SALES pool's hosted-UI domain. Blank derives an opaque default; a value here is published in DNS and CT logs and cannot be changed later.","example":"psp-a7f3c2-sales"},"customerAuthSubdomain":{"type":"string","description":"Optional DNS label for the CUSTOMER pool's hosted-UI domain. Blank derives an opaque default.","example":"psp-a7f3c2-customers"},"totpIssuer":{"type":"string","description":"Optional name shown in authenticator apps for this broker's users, on both pools. Blank uses the environment default (CurrencyGuard).","example":"Baumann Partners"}},"description":"Schema for representing a IntroducingBroker"},"RegulatedRequestFundedSettlement":{"required":["foreignAmount"],"type":"object","properties":{"foreignAmount":{"type":"number"},"customerId":{"type":"string","format":"uuid"}}},"RegulatedCancelFundingRequest":{"type":"object","properties":{"reason":{"type":"string"}}},"RegulatedRequestFundedSettlements":{"required":["settlements"],"type":"object","properties":{"settlements":{"type":"array","items":{"$ref":"#/components/schemas/RegulatedRequestFundedSettlementsLine"}},"customerId":{"type":"string","format":"uuid"}}},"RegulatedRequestFundedSettlementsLine":{"required":["foreignAmount","guardId"],"type":"object","properties":{"guardId":{"type":"string"},"foreignAmount":{"type":"number"}}},"RegulatedGuardQuoteDTO":{"required":["companyId","foreignCurrency","guardCurrency","guardSettlementWindowTo","introducingBrokerId","midAtInception","payReceive","salesUserId"],"type":"object","properties":{"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard quote (denormalized from company)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"salesUserId":{"type":"string","description":"ID of the sales user on whose behalf this quote is being created. Must belong to an introducing broker within the regulated entity.","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"customerId":{"type":"string","description":"ID of the customer who requested this quote","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"externalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference for the guard quote. Could be the beneficiary identifier or a foreign key in the PSP platform. Avoid using Personally Identifiable Information in this field.","example":"BEN-90210"},"invoiceExternalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference of the customer invoice this guard quote protects. Carried onto the guard when the quote is purchased. Avoid using Personally Identifiable Information in this field.","example":"INV-2024-001"},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The Guard currency is the currency in which the cost or receivable is being protected typically the corporate base currency","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of this guard, matching the invoice or bill currency","example":"USD"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"The traded currency pair this guard is booked on, in CurrencyPair convention. The guard currency may be either leg of this pair.","example":"GBPUSD"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":50000},"paymentMarginAtInception":{"type":"number","description":"Client payment margin inside the guard rate, as a decimal (0.015 = 1.5%). 0 = the guard rate is CGL's mid.","example":0.015},"midAtInception":{"type":"number","description":"The market mid the caller observed and priced against. Checked against CurrencyGuard's own feed; a mid outside tolerance is refused.","example":1.34},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMargin amount is calculated. If only salesMargin is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":0.007},"guardSettlementWindowTo":{"type":"string","description":"End settlement window of this guard in ISO 8601 format, typically the due date of the final payment","example":"2024-04-15T00:00:00Z"},"targetGuardAmountToSeekNetFees":{"type":"number","description":"Amount of the guard in the guard currency to seek for net of fees","example":60000},"salesMarginAmount":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency","example":296.02},"reason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the guard quote request","example":"Invoice protection for Q1 2024"},"payLater":{"type":"boolean","description":"Flag indicating whether fees should be paid later. Defaults to false if not specified.","example":false},"requestedGuardAmount":{"type":"number","description":"The funding requirement in the guard currency: the cap (Guard-Pay) or floor (Guard-Receive) the client is protected to, before fees. This is the client's own all-in price for the invoice, so the payment margin and the guard rate are DERIVED from it rather than sent -- amounts are exact to the cent, rates are 5dp roundings. Absent: CGL prices off its own mid with no payment margin, which is the pre-client-rate behaviour.","example":136010}},"description":"Schema for representing a GuardQuote"},"EntitlementsTemplateDTOCreate":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the entitlements template.","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"templateName":{"type":"string","description":"The unique name of the entitlements template.","example":"Super User"},"description":{"type":"string","description":"Description of what this template provides.","example":"Full administrative access with all permissions"},"userType":{"type":"string","description":"The user type this template applies to.","example":"REGULATED","enum":["INTERNAL","REGULATED","CUSTOMER","SALES"]},"entitlements":{"$ref":"#/components/schemas/EntitlementsDTO"},"isActive":{"type":"boolean","description":"Whether this template is active and can be assigned to users.","example":true}},"description":"Schema for representing a EntitlementsTemplate"},"ConfirmationTemplateDTOCreate":{"type":"object","properties":{"id":{"type":"string","description":"Unique template identifier","format":"uuid","example":"a0000000-0000-4000-8000-000000000001"},"documentType":{"type":"string","description":"Document type","example":"GUARD_CONFIRMATION"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID — NULL means default template","format":"uuid"},"templateName":{"type":"string","description":"Human-readable template name","example":"Default Guard Confirmation v1"},"templateBody":{"type":"string","description":"HTML template body with variable placeholders"},"effectiveFrom":{"type":"string","description":"Date from which this template version is effective","example":"2026-01-01T00:00:00Z"},"eventSequence":{"type":"integer","description":"Event sequence number for event-driven processing","format":"int64"},"versionNumber":{"type":"integer","description":"Optimistic locking version number","format":"int32","example":1},"updatedBy":{"type":"string","description":"User who last updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of last update in UTC","example":"2026-01-01T00:00:00Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2026-01-01T00:00:00Z"}},"description":"Schema for representing a ConfirmationTemplate"},"CreateApiClientRequestDTO":{"required":["clientName","description"],"type":"object","properties":{"clientName":{"maxLength":128,"minLength":0,"type":"string"},"description":{"maxLength":500,"minLength":0,"type":"string"}}},"ApiClientWithSecretDTO":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"clientName":{"type":"string"},"description":{"type":"string"},"cognitoClientId":{"type":"string"},"cognitoClientSecret":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"EventSubscriptionCreateRequestDTO":{"required":["callbackUrl","streamName","subscriberName"],"type":"object","properties":{"streamName":{"maxLength":50,"minLength":0,"type":"string","description":"The feed to subscribe to. A producing hexagon may publish more than one: trading publishes both 'trade' and 'trade-reference'.","example":"trade"},"subscriberName":{"maxLength":100,"minLength":0,"type":"string","description":"Name of the consuming processor. Must match the name it uses for its own event checkpoint.","example":"LedgerJournalFeedConsumer"},"callbackUrl":{"maxLength":500,"minLength":0,"type":"string","description":"Endpoint to which signed event batches will be POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/trade"},"initialEventSequence":{"type":"integer","description":"Cursor to start from. Events with a sequence GREATER than this are delivered. Omit or use -1 to receive the entire history. Honoured on creation only.","format":"int64","nullable":true,"example":4812},"maxBatchSize":{"minimum":1,"type":"integer","description":"Maximum number of events the dispatcher will put in one batch. Defaults to 100.","format":"int32","nullable":true,"example":100},"eventTypes":{"type":"array","description":"Event types to deliver. Omit to receive every type.","nullable":true,"example":["Guard","GuardSettlement"],"items":{"type":"string","description":"Event types to deliver. Omit to receive every type.","nullable":true,"example":"[\"Guard\",\"GuardSettlement\"]"}}},"description":"Request data for registering an internal event subscription"},"EventSubscriptionReplayRequestDTO":{"type":"object","properties":{"fromSequence":{"type":"integer","description":"First event sequence to redeliver (inclusive). Omit to replay from the beginning.","format":"int64","nullable":true,"example":4750}},"description":"Request data for restating an internal subscription's cursor"},"TradingEventSubscriptionDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this internal subscription","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"streamName":{"maxLength":50,"minLength":0,"type":"string","description":"The feed this subscriber consumes. Trading publishes more than one.","example":"trade","enum":["trade","trade-reference"]},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity that owns this subscription. NULL for an internal subscriber — that nullability is what distinguishes the two audiences.","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"subscriberName":{"maxLength":100,"minLength":0,"type":"string","description":"Name of the subscriber. For an internal consumer this matches its event checkpoint's processor_name; for a regulated entity it is a human-readable label.","example":"LedgerJournalFeedConsumer"},"payloadFormat":{"type":"string","description":"How event bodies are rendered. INTERNAL_RAW ships full internal state; PUBLIC_WHITELIST projects through an explicit field whitelist and a public event vocabulary.","example":"INTERNAL_RAW","enum":["INTERNAL_RAW","PUBLIC_WHITELIST"]},"deliveryUnit":{"type":"string","description":"Whether events are delivered as a bounded batch or one POST per event. Regulated entities receive single events — batching would break their published contract.","example":"BATCH","enum":["BATCH","SINGLE_EVENT"]},"callbackUrl":{"maxLength":500,"minLength":0,"type":"string","description":"Endpoint to which signed event batches are POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/trade"},"authMode":{"type":"string","description":"How we authenticate to this subscriber's endpoint. BEARER_AND_HMAC for an endpoint inside the platform's trust boundary; HMAC_ONLY for one outside it, which verifies us by signature alone.","example":"BEARER_AND_HMAC","enum":["BEARER_AND_HMAC","HMAC_ONLY"]},"status":{"type":"string","description":"Status of this subscription","example":"ACTIVE","enum":["ACTIVE","PAUSED","DISABLED","DELETED"]},"lastEventSequence":{"type":"integer","description":"Highest event sequence the subscriber has confirmed it committed. A resume hint, not the source of truth. -1 means nothing delivered yet.","format":"int64","example":4830},"maxBatchSize":{"type":"integer","description":"Maximum number of events the dispatcher will put in one batch","format":"int32","example":100},"eventTypes":{"$ref":"#/components/schemas/TradingEventSubscriptionDTOEventTypes"},"consecutiveFailures":{"type":"integer","description":"Number of consecutive delivery failures. Reset to 0 on success; subscription auto-pauses when the configured threshold is reached.","format":"int32","example":0},"lastPushAt":{"type":"string","description":"Timestamp of the most recent delivery attempt in UTC","example":"2026-05-30T14:23:01Z"},"lastPushStatus":{"type":"integer","description":"HTTP status code returned by the most recent delivery attempt","format":"int32","example":200},"lastErrorMessage":{"maxLength":500,"minLength":0,"type":"string","description":"Error message from the most recent failed delivery attempt","example":"Connection timed out after 10s"},"pausedAt":{"type":"string","description":"Timestamp when this subscription was paused (auto or manual) in UTC","example":"2026-05-30T14:23:01Z"},"lastRenewedAt":{"type":"string","description":"Timestamp of the subscriber's most recent registration renewal in UTC. Liveness signal.","example":"2026-05-30T14:23:01Z"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a EventSubscription"},"ProblemDetail":{"type":"object","properties":{"type":{"type":"string","description":"Stable URI identifying the problem type. This is the field to branch on; it resolves to documentation for the problem.","format":"uri","example":"https://developer.currencyguard.com/problems/guard-quote/quote-expired"},"title":{"type":"string","description":"Short human-readable summary, consistent for a given problem type.","example":"Quote Expired"},"status":{"type":"integer","description":"HTTP status code, repeated here for convenience.","format":"int32","example":409},"detail":{"type":"string","description":"Human-readable explanation of this specific occurrence. For display and logs only — the wording is not contract and must not be parsed.","example":"Quote has expired (age: 45 seconds, max: 30 seconds)"},"instance":{"type":"string","description":"Identifies the specific occurrence, normally the request path.","format":"uri","example":"/api-regulated/v1/guards"}},"description":"RFC 9457 problem details. Every error response from this API uses this shape, with the content type `application/problem+json`.\n\nBranch on `type`: it is a stable URI identifying the specific problem, it is the same in every environment, and it resolves to its own documentation. Do NOT branch on `detail` — that text is for humans and its wording may change at any time.\n\nResponses carry additional members beyond those below, specific to the problem type — for example a settlement rejected for exceeding the remaining balance carries `requested` and `unsettled`. The members for each type are documented at its `type` URI, and the full catalogue is available from `/api/v1/problem-types`.","example":{"type":"https://developer.currencyguard.com/problems/guard-settlement/settlement-exceeds-remaining","title":"Settlement Exceeds Remaining Amount","status":422,"detail":"Settlement amount (50000) exceeds unsettled balance (20000)","instance":"/api-regulated/v1/guards/1f3c.../settle-guard","requested":50000,"unsettled":20000,"correlationId":"9f2b7c14-3a5e-4a91-bb0e-72c5a1d8e004","timestamp":"2026-09-02T10:15:30Z"},"externalDocs":{"description":"Full catalogue of CurrencyGuard problem types, on this server","url":"/problems/"}},"EventBatchAckDTO":{"type":"object","properties":{"committedThrough":{"type":"integer","description":"Highest event sequence the subscriber has committed. Becomes the producer's new cursor.","format":"int64","example":4830}},"description":"Acknowledgement of a delivered event batch"},"ScheduleJobRequest":{"type":"object","properties":{"jobName":{"type":"string"},"jobGroup":{"type":"string"},"jobType":{"type":"string"},"cronExpression":{"type":"string"},"description":{"type":"string"}}},"ExportEvent":{"type":"object","properties":{"eventSequence":{"type":"integer","format":"int64"},"eventType":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"newState":{"$ref":"#/components/schemas/ExportEventNewState"}}},"ExportMetadata":{"type":"object","properties":{"exportDate":{"type":"string","format":"date-time"},"sourceEnvironment":{"type":"string"},"formatVersion":{"type":"string"}}},"TradeExportJson":{"type":"object","properties":{"exportMetadata":{"$ref":"#/components/schemas/ExportMetadata"},"guardQuotes":{"type":"array","items":{"$ref":"#/components/schemas/JsonNode"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/ExportEvent"}}}},"TradeImportResult":{"type":"object","properties":{"guardQuotesImported":{"type":"integer","format":"int32"},"guardsImported":{"type":"integer","format":"int32"},"guardSettlementsImported":{"type":"integer","format":"int32"},"fxOptionTradesImported":{"type":"integer","format":"int32"},"fxTradesImported":{"type":"integer","format":"int32"},"fxTradeLegsImported":{"type":"integer","format":"int32"},"totalEventsReplayed":{"type":"integer","format":"int32"},"errors":{"type":"array","items":{"type":"string"}}}},"EventSequenceRewind":{"type":"object","properties":{"previousSequence":{"type":"integer","description":"Sequence the processor was at before the rewind.","format":"int64","example":148213},"newSequence":{"type":"integer","description":"Sequence the processor was moved to.","format":"int64","example":148000},"message":{"type":"string","description":"Human-readable summary of what will be reprocessed."}},"description":"Result of rewinding an event stream processor."},"TradeEventProcessingRuleVersionDTOCreate":{"type":"object","properties":{"ruleVersion":{"type":"string","description":"Rule version identifier","example":"JERv1"},"description":{"type":"string","description":"Description of this rule version","example":"JournalEntry Entry Rule version 1"},"effectiveFrom":{"type":"string","description":"Date from which this rule version is effective","example":"2025-01-01T00:00:00Z"},"deprecatedAt":{"type":"string","description":"Date when this rule version was deprecated (null if still active)","example":"2025-12-31T23:59:59Z"}},"description":"Schema for representing a TradeEventProcessingRuleVersion"},"CloneRulesResponseDTO":{"type":"object","properties":{"sourceVersion":{"type":"string"},"newVersion":{"$ref":"#/components/schemas/TradeEventProcessingRuleVersionDTO"},"rulesCloned":{"type":"integer","format":"int32"}}},"TradeEventProcessHospitalDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"eventSource":{"type":"string","description":"The event counter event_sequence belongs to","example":"TRADING"},"eventSequence":{"type":"integer","description":"Event sequence number that failed processing. Only meaningful together with event_source.","format":"int64","example":12345},"processingType":{"type":"string","description":"Type of processing that failed (JOURNAL_ENTRY_PROCESSING, CASH_BALANCE_PROCESSING, etc.)","example":"JOURNAL_ENTRY_PROCESSING"},"ruleName":{"type":"string","description":"Name of the rule that was executing when failure occurred","example":"Guard Fee Received"},"patientStatus":{"type":"string","description":"Patient status: ERROR, PENDING_DISCHARGE, HEALED, DISCHARGED, IGNORE","example":"ERROR"},"failureDate":{"type":"string","description":"When error first occurred","example":"2025-12-10T14:30:00Z"},"lastFailureDate":{"type":"string","description":"When error most recently failed (for retry tracking)","example":"2025-12-11T09:15:00Z"},"retryCount":{"type":"integer","description":"Number of retry attempts","format":"int32","example":3},"errorMessage":{"type":"string","description":"Short error message (max 500 chars)","example":"Failed to evaluate amount: invalid JSON path"},"stackTrace":{"type":"string","description":"Full stack trace for debugging"},"versionNumber":{"type":"integer","description":"Optimistic locking version","format":"int32","example":1},"updatedBy":{"type":"string","description":"User who last updated this record","example":"system"},"createdAt":{"type":"string","description":"Timestamp of record creation","example":"2025-12-10T14:30:00Z"},"updatedAt":{"type":"string","description":"Timestamp of last update","example":"2025-12-11T09:15:00Z"}},"description":"Schema for representing a TradeEventProcessHospital"},"ShredKeyRequestDTO":{"required":["confirmation"],"type":"object","properties":{"confirmation":{"type":"string","description":"The perimeter's own id, retyped by the caller. Must match exactly.","example":"dddddddd-0000-4000-8000-000000000002"}},"description":"Confirmation for destroying a perimeter's key"},"PerimeterProgressDTO":{"type":"object","properties":{"perimeterId":{"type":"string","description":"The perimeter being advanced","format":"uuid","example":"dddddddd-0000-4000-8000-000000000002"},"status":{"type":"string","description":"Call /advance again while this is SWEEPING or RETIRING","example":"SWEEPING","enum":["PROVISIONING","SWEEPING","ACTIVE","RETIRING","RETIRED","DESTROYING","DESTROYED"]},"stage":{"type":"string","description":"The stage in a couple of words, for a heading or badge","example":"Re-encrypting"},"detail":{"type":"string","description":"What is happening and what it means for the data","example":"The entities have moved. Their data is being re-encrypted onto this perimeter's key and its documents copied into its bucket, a batch at a time."},"progress":{"type":"string","description":"The counts as a phrase, so every caller words it the same way","example":"37 of 412 moved"},"settled":{"type":"boolean","description":"Whether the operation has finished, so the caller can stop advancing","example":false},"done":{"type":"integer","description":"Rows and documents moved so far","format":"int64","example":37},"total":{"type":"integer","description":"Everything in scope — the denominator","format":"int64","example":412},"remaining":{"type":"integer","description":"Still to move. Zero means the next advance will seal the perimeter.","format":"int64","example":375},"percent":{"type":"integer","description":"done/total as a percentage, or 100 when there was nothing to do","format":"int32","example":9}},"description":"A perimeter's status and sweep progress after one step"},"SegregateRequestDTO":{"required":["rootEntityId","rootEntityType"],"type":"object","properties":{"rootEntityType":{"type":"string","description":"Which level of the tenant hierarchy to segregate. CurrencyGuard cannot be segregated — it is the root.","example":"INTRODUCING_BROKER","enum":["CURRENCYGUARD_COMPANY","REGULATED_ENTITY","INTRODUCING_BROKER","COMPANY"]},"rootEntityId":{"type":"string","description":"The entity to segregate. Everything beneath it that shares its current perimeter moves with it; anything already segregated stays where it is.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"ancestorAccess":{"type":"boolean","description":"Whether every ancestor perimeter's role may read and write the new perimeter's key and bucket. A regulated entity is accountable for its brokers, so this is normally true.","example":true,"default":true}},"description":"Segregate an entity into its own tenant perimeter"},"SegregationStartedDTO":{"type":"object","properties":{"perimeterId":{"type":"string","description":"The new perimeter. Pass this to /advance to drive the sweep to completion.","format":"uuid","example":"dddddddd-0000-4000-8000-000000000002"},"sourcePerimeterId":{"type":"string","description":"The perimeter this entity was moved out of. Everything not in scope stays there.","format":"uuid","example":"cccccccc-0000-4000-8000-000000000001"},"rootEntityType":{"type":"string","description":"Which level of the tenant hierarchy was segregated","example":"INTRODUCING_BROKER","enum":["CURRENCYGUARD_COMPANY","REGULATED_ENTITY","INTRODUCING_BROKER","COMPANY"]},"rootEntityId":{"type":"string","description":"The entity segregated, together with everything beneath it that shared the source perimeter","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"status":{"type":"string","description":"Where the saga has got to. SWEEPING means the cutover is done and the data is still moving onto the new key.","example":"SWEEPING","enum":["PROVISIONING","SWEEPING","ACTIVE","RETIRING","RETIRED","DESTROYING","DESTROYED"]}},"description":"The perimeter a segregation created, the entity it was created for, and how far it has got"},"MessageEnvelopeFXVolSurfaceQuoteDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXVolSurfaceQuoteDTO"}}},"FXOptionPositionDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this position specification","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"baseCurrency":{"type":"string","description":"Base currency of the option (the currency being bought/sold)","example":"GBP"},"quoteCurrency":{"type":"string","description":"Quote currency of the option (the currency used for pricing)","example":"USD"},"signedNotionalBase":{"type":"number","description":"Signed notional amount in base currency (positive = long, negative = short)","example":100000},"signedNotionalQuote":{"type":"number","description":"Signed notional amount in quote currency (positive = long, negative = short)","example":-125000},"notional":{"type":"number","description":"UNSIGNED notional amount in base currency (magnitude only, direction from optionBuySell). For signed values use signedNotionalBase.","example":100000},"strike":{"type":"number","description":"Strike price of the option (null for ATM options)","nullable":true,"example":1.25},"expiryDate":{"type":"string","description":"Option expiry date in ISO8601 format","example":"2025-12-31T00:00:00Z"},"optionCallPut":{"type":"string","description":"Whether this is a call or put option","example":"CALL","enum":["CALL","PUT"]},"optionBuySell":{"type":"string","description":"Whether this is a buy or sell position","example":"BUY","enum":["BUY","SELL"]},"optionStyle":{"type":"string","description":"Option style (European, American)","example":"EUROPEAN","enum":["AMERICAN","EUROPEAN"]},"deliveryMethod":{"type":"string","description":"Delivery method (Cash, Physical)","example":"PHYSICAL","enum":["CASH","PHYSICAL"]},"book":{"type":"string","description":"Book this position belongs to","nullable":true,"example":"GUARD_BOOK"},"deliverableAmount":{"type":"number","description":"Deliverable amount in quote currency (notional × strike)","nullable":true,"example":125000},"premiumBase":{"type":"number","description":"Premium amount in base currency (converted from premium currency using spot FX rates)","nullable":true,"example":800},"premiumQuote":{"type":"number","description":"Premium amount in quote currency (converted from premium currency using spot FX rates)","nullable":true,"example":1000}},"description":"Schema for representing a transient FX option position specification"},"FXOptionPositionValuationDTO":{"type":"object","properties":{"positionId":{"type":"string","description":"The unique identifier for this position valuation.","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"symbol":{"type":"string","description":"The currency pair symbol.","example":"GBPUSD"},"book":{"type":"string","description":"The book this position belongs to.","example":"GUARD_BOOK"},"positionDirection":{"type":"string","description":"The position direction (BUY or SELL).","example":"BUY","enum":["BUY","SELL"]},"positionAmount":{"type":"number","description":"The position notional amount.","example":100000},"positionCurrency":{"type":"string","description":"The position currency (base currency of the option).","example":"GBP"},"position":{"$ref":"#/components/schemas/FXOptionPositionDTO"},"quoteCurrency":{"type":"string","description":"The quote currency for premium and mark-to-market.","example":"USD"},"valuation":{"$ref":"#/components/schemas/ValuationDTO"},"sourceGuard":{"$ref":"#/components/schemas/GuardDTOInternal"},"sourceGuardSettlement":{"$ref":"#/components/schemas/GuardSettlementDTOInternal"},"sourceHedgeOption":{"$ref":"#/components/schemas/FXOptionTradeDTO"},"positionSourceType":{"type":"string","description":"The type of source this position was derived from.","nullable":true,"enum":["GUARD","GUARD_SETTLEMENT","HEDGE_OPTION"]},"hedgeId":{"type":"string","description":"The hedge option ID associated with this position. For GUARD: guard.backToBackHedge.id, for GUARD_SETTLEMENT: sourceGuardSettlement.backToBackHedge.id, for HEDGE_OPTION: sourceHedgeOption.id.","nullable":true,"example":"OSP1000104"},"includedInRiskAggregation":{"type":"boolean"}},"description":"Schema for representing an FX option position valuation with risk metrics"},"FXOptionPositionValuationWithRiskStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXOptionPositionValuationDTO"}},"description":"Container for FX option position valuation data with state information. The 'value' field contains valuation details and can be present even when valid=false (stale/approximate data)."},"FXOptionPriceDTO":{"type":"object","properties":{"symbol":{"type":"string","description":"The symbol representing the option.","example":"GBPUSD"},"callPut":{"type":"string","description":"Indicates if the option is a call or a put.","example":"CALL","enum":["CALL","PUT"]},"bidVol":{"type":"number","description":"The bid volatility rate for the option.","example":0.119},"askVol":{"type":"number","description":"The ask volatility rate for the option.","example":0.121},"askPrice":{"type":"number","description":"The ask price for the option.","example":1.25},"bidPrice":{"type":"number","description":"The bid price for the option.","example":1.245},"spotAskPrice":{"type":"number","description":"The spot ask price.","example":1.246},"spotBidPrice":{"type":"number","description":"The spot bid price.","example":1.2455},"strikePrice":{"type":"number","description":"The strike price of the option.","example":1.24},"expiryDate":{"type":"string","description":"The expiry date of the option, in ISO8601 format.","example":"2025-12-31T00:00:00Z"},"lastUpdated":{"type":"string","description":"The last updated timestamp for this option price in ISO8601 format.","example":"2024-10-01T12:00:00Z"},"bidVega":{"type":"number","description":"Bid vega (negative for SELL positions)","example":-0.1},"askVega":{"type":"number","description":"Ask vega (positive for BUY positions)","example":0.1},"bidGamma":{"type":"number","description":"Bid gamma (negative for SELL positions)","example":-0.05},"askGamma":{"type":"number","description":"Ask gamma (positive for BUY positions)","example":0.05},"quoteBidInterestRate":{"type":"number","description":"The quote currency bid interest rate for the option.","example":0.02},"quoteAskInterestRate":{"type":"number","description":"The quote currency ask interest rate for the option.","example":0.02},"baseBidInterestRate":{"type":"number","description":"The base currency bid interest rate for the option.","example":0.03},"baseAskInterestRate":{"type":"number","description":"The base currency ask interest rate for the option.","example":0.03},"forwardBidRate":{"type":"number","description":"Forward bid rate at expiry tenor (spot bid + bid swap points)","example":1.245},"forwardAskRate":{"type":"number","description":"Forward ask rate at expiry tenor (spot ask + ask swap points)","example":1.246},"forwardMidRate":{"type":"number","description":"Forward mid rate at expiry tenor (spot mid + mid swap points)","example":1.2455},"swapPointsBid":{"type":"number","description":"Forward swap points bid (forward bid - spot bid)","example":-0.001},"swapPointsAsk":{"type":"number","description":"Forward swap points ask (forward ask - spot ask)","example":-0.0005},"swapPointsMid":{"type":"number","description":"Forward swap points mid (forward mid - spot mid)","example":-0.00075},"priceExplain":{"type":"string","description":"Price explanation detailing how the option price was calculated","nullable":true}},"description":"Schema for representing an option price","example":{"premium":1250.5,"delta":0.45,"gamma":0.02}},"FXOptionPriceStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXOptionPriceDTO"}},"description":"Container for FX option price data with state information. The 'value' field contains pricing details and can be present even when valid=false (stale/approximate data)."},"FXOptionTradeDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this vanilla FX option. A hedge option reuses its owning Guard/settlement reference with the leading G swapped for O (e.g. OSP1000104-E01); a standalone option is OCG0000001-style.","example":"OSP1000104"},"originalGuardId":{"type":"string","description":"ID of the original guard that this option was created to hedge. Used to track all hedge options across guard extensions.","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this option","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this option was traded with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"tradeDate":{"type":"string","description":"Trade date - the date when the option trade was executed","example":"2025-01-15T10:30:00Z"},"premiumDate":{"type":"string","description":"Premium date - the date when the option premium is settled (derived from trade date)","example":"2025-01-15"},"optionBuySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Indicates whether the option is a buy or sell","example":"BUY","enum":["BUY","SELL"]},"optionStatus":{"pattern":"^(PENDING_BUY|PENDING_SELL|BOUGHT|SOLD|PENDING_CANCEL|CANCELLED)$","type":"string","description":"Status of the option","example":"BOUGHT","enum":["PENDING_BUY","PENDING_SELL","BOUGHT","SOLD","PENDING_CANCEL","CANCELLED"]},"optionCallPut":{"pattern":"^(CALL|PUT)$","type":"string","description":"Specifies if the option is a call or put","example":"CALL","enum":["CALL","PUT"]},"strike":{"type":"number","description":"Strike price of the option","example":1.25},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time of trade execution","example":1.25123},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time of trade execution","example":1.25145},"expiryDate":{"type":"string","description":"Date when the option expires","example":"2025-12-31"},"settlementDate":{"type":"string","description":"Settlement date - the date when the option settles, typically T+2 after expiry (derived from expiry date)","example":"2026-01-02"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the option","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the option","example":"USD"},"notional":{"type":"number","description":"Notional amount of the option in the base currency","example":100000},"premium":{"type":"number","description":"Premium paid for the option","example":5000},"premiumCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is denominated","example":"USD"},"premiumSettlementAmount":{"type":"number","description":"Amount of the premium in the settlement currency","example":5000},"premiumSettlementCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is settled","example":"GBP"},"optionPrice":{"type":"number","description":"Price of the option","example":0.05},"optionStyle":{"pattern":"^(AMERICAN|EUROPEAN)$","type":"string","description":"Style of the option","example":"EUROPEAN","enum":["AMERICAN","EUROPEAN"]},"deliveryMethod":{"pattern":"^(CASH|PHYSICAL)$","type":"string","description":"Delivery method of the option","example":"CASH","enum":["CASH","PHYSICAL"]},"statusReason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the option's status","example":"Awaiting approval"},"traderId":{"type":"string","description":"ID of the internalUser managing this option","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"book":{"maxLength":30,"minLength":0,"type":"string","description":"Book this option resides in","example":"Guard Book"},"priceExplain":{"maxLength":50000,"minLength":0,"type":"string","description":"Price explain for this option"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"deliverableAmount":{"type":"number","description":"Deliverable amount in quote currency (notional × strike)","example":125000}},"description":"Schema for representing a FXOptionTrade"},"GuardDTOInternal":{"type":"object","properties":{"id":{"type":"string","description":"Reference for this guard. The original is bare; extensions carry an -E{nn} suffix.","example":"GSP1000104"},"originalGuardId":{"type":"string","description":"Id of the original Guard at the start of the lifecycle. Constant through extensions.","example":"GSP1000104"},"previousGuardId":{"type":"string","description":"Id of the Guard generation this one extended. NULL on an original.","example":"GSP1000104"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty for this guard (derived from regulated entity)","format":"uuid","example":"22222222-2222-4222-8222-222222222222"},"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard (denormalized from company)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedUserId":{"type":"string","description":"ID of the regulated user who booked this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"salesUserId":{"type":"string","description":"ID of the sales user who sold this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"customerId":{"type":"string","description":"ID of the customer who owns this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"guardStatus":{"type":"string","description":"Status of this guard","example":"ACTIVE","enum":["ERROR","CANCELLED","PENDING","AWAITING_FEE","ACTIVE","COMPLETE","LAPSED","VOID","EXTENDED"]},"statusReason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the status of this guard","example":"The guard is pending a fee payment"},"externalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference for the guard. Could be the beneficiary identifier or a foreign key in the PSP platform. Avoid using Personally Identifiable Information in this field.","example":"BEN-90210"},"invoiceExternalRef":{"maxLength":36,"minLength":0,"type":"string","description":"External reference of the customer invoice this guard protects. Copied from the guard quote at purchase. Avoid using Personally Identifiable Information in this field.","example":"INV-2024-001"},"guardPeriodFrom":{"type":"string","description":"Start period date of this guard, also the purchase date","example":"2024-01-16"},"tradeDate":{"type":"string","description":"Trade date for this guard. The actual transaction datetime when the guard was created or extended.","example":"2024-01-16T11:00:00Z"},"settlementWindowFrom":{"type":"string","description":"Start settlement window of this guard, typically two weeks due date of the final payment","example":"2024-01-16"},"settlementWindowTo":{"type":"string","description":"End settlement window of this guard, typically the due date of the final payment","example":"2024-04-15"},"guardPeriodTo":{"type":"string","description":"End period date of this guard, typically one day after the due date of the final payment","example":"2024-04-15"},"guardPeriodToValueDate":{"type":"string","description":"Settlement date of the guard, calculated as guard_period_to + 2 business days. Must match the settlement date on the back-to-back hedge.","example":"2024-04-17"},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The Guard currency is the currency in which the cost or receivable is being protected typically the corporate base currency","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of this guard, matching the invoice or bill currency","example":"USD"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"The traded currency pair this guard is booked on, in CurrencyPair convention. The guard currency may be either leg of this pair.","example":"GBPUSD"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the guard will pay or receive foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"Amount of the guard in the foreign currency","example":50000},"totalForeignAmountSettled":{"type":"number","description":"Total foreign amount settled so far in the foreign currency","example":15000},"guardRate":{"type":"number","description":"Guard rate of exchange","example":1.3121},"paymentMarginAtInception":{"type":"number","description":"Client payment margin inside the guard rate, frozen at inception, as a decimal (0.015 = 1.5%)","example":0.015},"midAtInception":{"type":"number","description":"CGL market mid the guard rate was derived from, copied from the guard quote","example":1.34},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time the guard was created, copied from the guard quote","example":1.3115},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time the guard was created, copied from the guard quote","example":1.3125},"guardAmount":{"type":"number","description":"Guard amount in the guard currency, derived from the foreign amount and guard rate","example":38109.75},"totalGuardAmountSettled":{"type":"number","description":"Total guard amount settled so far in the guard currency","example":11432.92},"totalDeclaredMarginSettled":{"type":"number","description":"Running sum of declaredMarginPct x settlement guardAmount across all SETTLED settlements on this guard, in guard currency","example":1200},"totalTrueUpAmountSettled":{"type":"number","description":"Running sum of trueUpAmount across all SETTLED settlements on this guard, in guard currency","example":100},"guardFee":{"type":"number","description":"Fee paid for the guard in the guard currency","example":512},"guardFeeDate":{"type":"string","description":"Guard fee payment date, calculated as trade_date + 2 business days. Corresponds to the premium payment date on the back-to-back hedge.","example":"2024-01-18"},"isFeePaid":{"type":"boolean","description":"Whether the guard fee has been confirmed received. Independent of guard_status: the fee-cleared event and the hedge-confirmed transition are not ordered relative to each other, so this can flip true while the guard is still PENDING.","example":false},"guardMarginRate":{"type":"number","description":"Guard margin rate as a percentage","example":0.007},"guardMargin":{"type":"number","description":"Guard margin amount incorporated into the guard fee and expressed in guard currency","example":296.02},"volSpreadMultiplier":{"type":"number","description":"Vol spread multiplier applied to the market vol bid/ask when this Guard was priced. 1.0 = unadjusted market spread.","example":2},"valuationStrike":{"type":"number","description":"Valuation rate this Guard was priced against: the mid rounded to 0.0005 in CGL's favour","example":1.34},"valuationNotional":{"type":"number","description":"Valuation notional in the foreign currency: guard amount divided by the valuation rate","example":101500},"salesMarginRate":{"type":"number","description":"Sales margin rate as a decimal (e.g. 0.007 = 0.7%). If only salesMarginRate is provided, salesMargin amount is calculated. If only salesMargin is provided, salesMarginRate is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":0.007},"salesMargin":{"type":"number","description":"Sales margin amount incorporated into the guard fee and expressed in guard currency. If only salesMargin is provided, salesMarginRate is calculated. If only salesMarginRate is provided, salesMargin amount is calculated. If both are provided, they must match within a tolerance of 0.01 or the request is rejected with 400 Bad Request.","example":296.02},"effectiveRate":{"type":"number","description":"Effective rate to the client after all costs including the Guard fee and margins","example":1.2946},"guardQuoteId":{"type":"string","description":"ID of the guard quote that was used to create this guard","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"backToBackHedgeId":{"type":"string","description":"ID of the back-to-back hedge","example":"OSP1000104"},"totalPendingHedgeCount":{"type":"integer","description":"Number of outstanding back-to-back hedges for this guard and its associated guard settlements that are in status PENDING_NEW","format":"int32","example":1},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp when of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Guard"},"GuardSettlementDTOInternal":{"type":"object","properties":{"id":{"type":"string","description":"Reference for this settlement, appended to the Guard generation it settled.","example":"GSP1000104-E01-S02"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty for this guard settlement (inherited from guard)","format":"uuid","example":"22222222-2222-4222-8222-222222222222"},"introducingBrokerId":{"type":"string","description":"ID of the introducing broker for this guard settlement (denormalized from guard)","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"regulatedUserId":{"type":"string","description":"ID of the regulated user who booked this guard settlement","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"salesUserId":{"type":"string","description":"ID of the sales user who sold this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"companyId":{"type":"string","description":"ID of the company associated with this payment","format":"uuid"},"customerId":{"type":"string","description":"ID of the customer who owns this guard","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"settlementDate":{"type":"string","description":"Settlement date of this guard settlement, when the FX conversion occurs","example":"2024-04-09"},"paymentDate":{"type":"string","description":"Payment date, calculated as settlement_date + 2 business days. The date when funds are actually transferred","example":"2024-04-11"},"guardPeriodFrom":{"type":"string","description":"Start period date of this guard, also the purchase date","example":"2024-01-16"},"guardFeeDate":{"type":"string","description":"Guard fee payment date, calculated as guard_period_from + 2 business days. Corresponds to the premium payment date on the back-to-back hedge.","example":"2024-01-18"},"settlementWindowFrom":{"type":"string","description":"Start settlement window of this guard, typically two weeks due date of the final payment","example":"2024-01-16"},"settlementWindowTo":{"type":"string","description":"End settlement window of this guard, typically the due date of the final payment","example":"2024-04-15"},"guardPeriodTo":{"type":"string","description":"End period date of this guard, typically one day after the due date of the final payment","example":"2024-04-15"},"guardPeriodToValueDate":{"type":"string","description":"Settlement date of the guard, calculated as guard_period_to + 2 business days. Must match the settlement date on the back-to-back hedge.","example":"2024-04-17"},"guardSettlementStatus":{"pattern":"^(AWAITING_FUNDING|EXECUTION_PENDING|FUNDING_LAPSED|FUNDING_CANCELLED|SETTLEMENT_PENDING|SETTLEMENT_EXECUTED|SETTLEMENT_REJECTED|EXTENSION_PENDING|EXTENSION_EXECUTED|CANCELLATION_PENDING|CANCELLATION_EXECUTED|VOID_EXECUTED)$","type":"string","description":"Status of this settlement","example":"SETTLEMENT_EXECUTED","enum":["AWAITING_FUNDING","EXECUTION_PENDING","FUNDING_LAPSED","FUNDING_CANCELLED","SETTLEMENT_PENDING","SETTLEMENT_EXECUTED","SETTLEMENT_REJECTED","EXTENSION_PENDING","EXTENSION_EXECUTED","CANCELLATION_PENDING","CANCELLATION_EXECUTED","VOID_EXECUTED"]},"batchId":{"maxLength":10,"minLength":0,"type":"string","description":"Settlement batch this row was requested as part of, if any","example":"BSP0000042"},"statusReason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the status of this settlement","example":"The reference rate is out of tolerance"},"payReceive":{"pattern":"^(PAY|RECEIVE)$","type":"string","description":"Indicates whether the settlement is for the payment or receipt of foreign currency","example":"PAY","enum":["PAY","RECEIVE"]},"guardCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Guard currency, the currency in which the cost or receivable is being protected.","example":"GBP"},"foreignCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Foreign currency of the settlement, matches the invoice or bill currency","example":"EUR"},"foreignAmount":{"type":"number","description":"Foreign amount the customer paid or received in the foreign currency for this settlement","example":75000},"guardRate":{"type":"number","description":"Guard rate from the original guard contract","example":1.1405},"guardAmount":{"type":"number","description":"Protected amount in guard currency - what the customer is guaranteed to receive/pay at the guard rate (foreign_amount ÷ guard_rate)","example":65760.63},"deliveredAmount":{"type":"number","description":"Amount CGL delivers to the client at settlement, in delivered_currency. Pay: the invoice in foreign currency. Receive: the floor or the all-in in guard currency.","example":100000},"deliveredCurrency":{"type":"string","description":"Currency of delivered_amount. Guard-Pay: foreign currency. Guard-Receive: guard currency.","example":"GBP"},"shortfallAmount":{"type":"number","description":"Amount the guard pays out when market moves unfavorably. For Guard-Receive: in guard currency (guard_amount - conversion_amount). For Guard-Pay: in foreign currency (foreign_amount × (guard_rate - conversion_rate) / guard_rate). Zero or positive when guard provides protection.","example":2147.4},"shortfallCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency of the shortfall amount. Guard-Receive: guard currency. Guard-Pay: foreign currency.","example":"GBP"},"savingsRebateAmount":{"type":"number","description":"Savings-zone rebate owed to the client on a funded settlement, in the funding currency","example":1660.12},"savingsRebateCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency of the savings rebate","example":"USD"},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time of settlement","example":1.17895},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time of settlement","example":1.17905},"conversionRate":{"type":"number","description":"Actual market FX rate at settlement time used for the conversion","example":1.179},"conversionAmount":{"type":"number","description":"What the tranche costs/yields the client at their own all-in rate (mid plus the declared payment margin). Above the guard amount means the Guard is protecting.","example":139055},"executedConversionRate":{"type":"number","description":"The rate CGL actually converted at with the regulated entity at execution, versus conversion_rate which is the mid.","example":1.3670475},"conversionProceeds":{"type":"number","description":"Proceeds CGL received from the execution conversion, in the bought currency.","example":99491.79},"reFxMarginAmount":{"type":"number","description":"The regulated entity's FX margin earned on CGL's execution conversion, in guard currency. Feeds the month-end true-up.","example":203.76},"declaredMarginPct":{"type":"number","description":"Client payment margin declared at settlement, as a decimal (0.016 = 1.6%)","example":0.016},"trueUpAmount":{"type":"number","description":"Signed CGL/RE margin true-up in the guard currency. Positive means the regulated entity owes CurrencyGuard; negative means CurrencyGuard owes the regulated entity.","example":685},"settlementZone":{"pattern":"^(PROTECTION|SAVINGS|NOT_APPLICABLE|UNKNOWN)$","type":"string","description":"Whether the Guard paid out on this tranche. PROTECTION: the client's own cost is above the cap, CGL funds the shortfall. SAVINGS: it is below, the client settles at market and CGL is not involved. NOT_APPLICABLE: a cancellation or void, where nothing was converted.","example":"PROTECTION","enum":["PROTECTION","SAVINGS","NOT_APPLICABLE","UNKNOWN"]},"refundAmount":{"type":"number","description":"Refund amount returned to client for guard cancellation in guard currency. Only populated for cancellation settlements.","example":334},"refundCalculation":{"$ref":"#/components/schemas/GuardSettlementDTOInternalRefundCalculation"},"salesMarginAmount":{"type":"number","description":"Sales margin amount applied to the conversion rate as a rate (e.g. 0.01 = 1%). Positive means sales took margin, negative means customer got better than market rate.","example":0.0025},"totalForeignAmountSettled":{"type":"number","description":"Total foreign amount settled on the guard BEFORE this settlement (cumulative from previous settlements)","example":20000},"totalGuardAmountSettled":{"type":"number","description":"Total guard amount settled on the guard BEFORE this settlement (cumulative from previous settlements)","example":15243.9},"guardId":{"type":"string","description":"ID of the guard associated with this payment","example":"1b6453892-e5e1-4fad-9e9b-4fa4e60f6c2b"},"originalGuardId":{"type":"string","description":"ID of the original guard at the start of the lifecycle. Remains constant through extensions and other lifecycle changes.","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"backToBackHedgeId":{"type":"string","description":"ID of the back-to-back hedge","example":"OSP1000104-S01"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"creditorReference":{"type":"string","description":"RF creditor reference to quote when funding this settlement","example":"RF13GIX0000001S01"},"fundingCurrency":{"type":"string","description":"Currency the client sends to fund this settlement","example":"USD"},"fundingAmount":{"type":"number","description":"Amount the client sends to fund this settlement","example":20000}},"description":"Schema for representing a GuardSettlement"},"MessageEnvelopeFXOptionPositionValuationWithRiskStateDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXOptionPositionValuationWithRiskStateDTO"}}},"ValuationDTO":{"type":"object","properties":{"marketPrice":{"$ref":"#/components/schemas/FXOptionPriceStateDTO"},"markToMarketValue":{"type":"number","description":"Mark-to-market value in quote currency (uses appropriate bid/ask for buy/sell direction).","example":1250},"deltaExposure":{"type":"number","description":"Net delta exposure in base currency: position amount x market delta.","example":500},"vegaExposure":{"type":"number","description":"Net vega exposure in base currency: position amount x market vega x 0.01 (per 1% vol).","example":75},"gammaExposure":{"type":"number","description":"Net gamma exposure in base currency: position amount x market gamma x 0.01 (per 100 pips).","example":25},"markToMarketMidValue":{"type":"number","description":"Mid-market mark-to-market value in quote currency (position-aware signed).","example":1200},"deltaMidExposure":{"type":"number","description":"Mid delta exposure in base currency (position-aware signed).","example":475},"vegaMidExposure":{"type":"number","description":"Mid vega exposure in base currency (position-aware signed).","example":70},"gammaMidExposure":{"type":"number","description":"Mid gamma exposure in base currency (position-aware signed).","example":23},"valuationTimestamp":{"type":"string","description":"Timestamp when this valuation was calculated, in ISO8601 format.","example":"2024-10-01T12:00:00Z"},"pricingSide":{"type":"string","description":"The pricing side used for this valuation. ENTRY uses ASK for BUY, BID for SELL. LIQUIDATION uses BID for BUY (long position value), ASK for SELL (short position liability).","example":"LIQUIDATION","enum":["ENTRY","LIQUIDATION"]},"priceExplain":{"type":"string","description":"Portfolio-level price explanation showing position-scaled calculations and unitary pricing details.","nullable":true}},"description":"Valuation metrics for an FX option position against a single market data snapshot"},"FXForwardCurveDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this forward point curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this forward point curve","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this forward curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXForwardCurveDTOModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the forward point curve data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXForwardCurve"},"FXForwardCurveStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXForwardCurveDTO"}},"description":"Container for FX forward curve data with state information. The 'value' field contains curve details and can be present even when valid=false (stale/approximate data)."},"FXVolSurfaceDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this volatility surface","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for this volatility surface","example":"GBPUSD"},"valuationDatetime":{"type":"string","description":"The instant this surface is valued at, in UTC. The vendor's own time where they assert one, otherwise the instant the cutoff designates. Not a rounded cutoff time -- see the note above this table","example":"2024-02-11T09:00:02Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Label designating this surface as the official marks for a valuation point. Vendor-stated where given, otherwise derived from valuation_datetime","example":"0900LON"},"model":{"$ref":"#/components/schemas/FXVolSurfaceDTOModel"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the volatility surface data","example":"MANUAL"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXVolSurface"},"FXVolSurfaceStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXVolSurfaceDTO"}},"description":"Container for FX volatility surface data with state information. The 'value' field contains vol surface details and can be present even when valid=false (stale/approximate data)."},"MarketDataBundleDTO":{"type":"object","properties":{"currencyPair":{"type":"string","description":"The currency pair","example":"GBPUSD"},"timestamp":{"type":"string","description":"The timestamp in ISO8601 format","example":"2024-02-15T14:30:00Z"},"domesticCalendar":{"$ref":"#/components/schemas/TradingCalendarDTO"},"foreignCalendar":{"$ref":"#/components/schemas/TradingCalendarDTO"},"tradingCalendar":{"$ref":"#/components/schemas/TradingCalendarDTO"},"spotPrice":{"$ref":"#/components/schemas/FXPriceStateDTO"},"baseCurrencyDomesticRate":{"$ref":"#/components/schemas/FXPriceStateDTO"},"baseCurrencyForeignRate":{"$ref":"#/components/schemas/FXPriceStateDTO"},"baseZeroRateCurve":{"$ref":"#/components/schemas/ZeroRateCurveStateDTO"},"quoteZeroRateCurve":{"$ref":"#/components/schemas/ZeroRateCurveStateDTO"},"forwardRateCurve":{"$ref":"#/components/schemas/FXForwardCurveStateDTO"},"volStrikeSurface":{"$ref":"#/components/schemas/FXVolSurfaceStateDTO"}},"description":"Schema for representing market data bundle"},"MarketDataBundleStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/MarketDataBundleDTO"}},"description":"Container for market data bundle with state information. The 'value' field contains market data and can be present even when valid=false (stale/approximate data)."},"MessageEnvelopeMarketDataBundleStateDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/MarketDataBundleStateDTO"}}},"NonBusinessDayDTO":{"type":"object","properties":{"date":{"type":"string","description":"Date in ISO format","example":"2025-01-01"},"calendars":{"type":"array","description":"List of calendar codes that consider this date non-business","items":{"type":"string","description":"List of calendar codes that consider this date non-business"}},"description":{"type":"string","description":"Holiday description","example":"New Year's Day"}},"description":"Non-business day information with grouped calendar codes"},"TradingCalendarDTO":{"type":"object","properties":{"symbol":{"type":"string","description":"Calendar symbol (GBPUSD for FX settlement, GBP for domestic, USNY for financial center)","example":"GBPUSD"},"calendars":{"type":"array","description":"List of calendar codes that apply to this symbol","items":{"type":"string","description":"List of calendar codes that apply to this symbol"}},"isSundayBusinessDate":{"type":"boolean","description":"Whether Sunday is considered a business day","example":false},"isMondayBusinessDate":{"type":"boolean","description":"Whether Monday is considered a business day","example":true},"isTuesdayBusinessDate":{"type":"boolean","description":"Whether Tuesday is considered a business day","example":true},"isWednesdayBusinessDate":{"type":"boolean","description":"Whether Wednesday is considered a business day","example":true},"isThursdayBusinessDate":{"type":"boolean","description":"Whether Thursday is considered a business day","example":true},"isFridayBusinessDate":{"type":"boolean","description":"Whether Friday is considered a business day","example":true},"isSaturdayBusinessDate":{"type":"boolean","description":"Whether Saturday is considered a business day","example":false},"nonBusinessDays":{"type":"array","description":"List of non-business days with their applicable calendars","items":{"$ref":"#/components/schemas/NonBusinessDayDTO"}}},"description":"Trading calendar with grouped holiday display format"},"ZeroRateCurveDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this interest rate curve","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyCode":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code this curve applies to","example":"GBP"},"source":{"maxLength":25,"minLength":2,"pattern":"^[A-Z0-9_]+$","type":"string","description":"Source of the curve data","example":"MANUAL"},"valuationDatetime":{"type":"string","description":"Valuation datetime for this curve snapshot in UTC","example":"2024-02-11T09:00:00Z"},"cutoff":{"pattern":"^\\d{4}LON$","type":"string","description":"Market data cutoff time in London timezone","example":"0900LON"},"model":{"$ref":"#/components/schemas/ZeroRateCurveDTOModel"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a ZeroRateCurve"},"ZeroRateCurveStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/ZeroRateCurveDTO"}},"description":"Container for zero rate curve data with state information. The 'value' field contains curve details and can be present even when valid=false (stale/approximate data)."},"MessageEnvelopeInterestRateCurveQuoteDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/InterestRateCurveQuoteDTO"}}},"MessageEnvelopeGuardQuoteStateDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/GuardQuoteStateDTO"}}},"MessageEnvelopeGuardDTOInternal":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/GuardDTOInternal"}}},"FXPositionPnLValuationDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this position P&L entry","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"currencyPair":{"type":"string","description":"Currency pair for this position","example":"GBPUSD"},"valueDate":{"type":"string","description":"Settlement value date for this position bucket","example":"2025-12-23T00:00:00Z"},"sourceEntityId":{"type":"string","description":"ID of the source entity that generated this P&L lot","example":"CCG0000001"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this position","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty the originating trade was executed with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"fxTradeEventSequence":{"type":"integer","description":"Event sequence of the originating trade","format":"int64","example":12345},"eventSequence":{"type":"integer","description":"Own event sequence number from the global trade event sequence","format":"int64","example":12346},"tradeTimestamp":{"type":"string","description":"Execution timestamp of the trade","example":"2025-12-21T09:30:00Z"},"buySell":{"type":"string","description":"Direction of this lot","example":"BUY"},"originalAmount":{"type":"number","description":"Original trade amount in the base currency","example":100000},"price":{"type":"number","description":"Trade execution price","example":1.25},"remainingAmount":{"type":"number","description":"Remaining open amount after FIFO matching","example":60000},"position":{"type":"number","description":"Running net position in base currency after this lot is processed","example":60000},"averageCost":{"type":"number","description":"Running weighted average cost of the open position","example":1.2531},"incrementalRealisedPnl":{"type":"number","description":"Incremental realised P&L for this lot in quote currency","example":250},"versionNumber":{"type":"integer","description":"Version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username that last updated this record","example":"TradeEventProcessor"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"markPrice":{"type":"number","description":"Mark-to-market price (forward-interpolated or spot fallback)","example":1.2612},"unrealisedPnl":{"type":"number","description":"Unrealised P&L in quote currency","example":1000}},"description":"FX Position P&L with mark-to-market valuation and unrealised P&L (flattened)"},"FXPositionPnLValuationStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXPositionPnLValuationDTO"}},"description":"FX Position P&L valuation with state information (valid/error) and source metadata."},"MessageEnvelopeFXPositionPnLValuationStateDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXPositionPnLValuationStateDTO"}}},"MessageEnvelopeFXOptionTradeDTO":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MessageHeader"},"body":{"$ref":"#/components/schemas/FXOptionTradeDTO"}}},"SettlementDTOCreate":{"required":["bankAccountCode","counterpartyId","currency","valueDate"],"type":"object","properties":{"counterpartyId":{"type":"string","description":"UUID of the counterparty whose balances are being settled","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currency":{"type":"string","description":"ISO 4217 currency code","example":"USD"},"valueDate":{"type":"string","description":"Value date of the entries to settle in ISO 8601 date format (yyyy-MM-dd)","example":"2025-12-20"},"settlementDate":{"type":"string","description":"Settlement date in ISO 8601 date format (yyyy-MM-dd). Defaults to today if not provided.","example":"2025-12-21"},"bankAccountCode":{"type":"string","description":"Bank account code where the cash movement is recorded (must be category=CASH)","example":"1010"},"description":{"maxLength":500,"minLength":0,"type":"string","description":"Optional description of the settlement","example":"Settlement of EUR receivables from ACME Corp"},"settlementAmount":{"type":"number","description":"Optional settlement amount (absolute value). The direction (paying vs receiving) is determined automatically based on whether the outstanding balance is a payable or receivable. If not provided, settles for the exact outstanding balance (Full Settlement). If amount > outstanding balance, creates prepayment (Over-Settlement). If amount < outstanding balance, partial settlement (Under-Settlement). Example: To pay 2000 EUR against a 4196 EUR payable, send 2000.00","example":2000}},"description":"Request to create a cash settlement reconciliation"},"SettlementDTO":{"type":"object","properties":{"counterpartyId":{"type":"string","description":"UUID of the counterparty whose balances were settled","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currency":{"type":"string","description":"ISO 4217 currency code","example":"USD"},"valueDate":{"type":"string","description":"Value date of the settled entries in ISO 8601 date format","example":"2025-12-20"},"settlementDate":{"type":"string","description":"Settlement date in ISO 8601 date format","example":"2025-12-21"},"bankAccountCode":{"type":"string","description":"Bank account code where the cash movement was recorded","example":"1010"},"description":{"type":"string","description":"Description of the settlement","example":"Settlement of EUR receivables from ACME Corp"},"netAmount":{"type":"number","description":"Net settlement amount (positive = cash in, negative = cash out)","example":15000},"accountsCleared":{"type":"integer","description":"Number of AR/AP accounts cleared by this settlement","format":"int32","example":3},"journalEntriesCreated":{"type":"integer","description":"Total number of journal entries created (including bank entry)","format":"int32","example":7},"journalEntries":{"type":"array","description":"Detailed list of all journal entries created by this settlement","items":{"$ref":"#/components/schemas/SettlementJournalEntryDTO"}},"createdAt":{"type":"string","description":"Timestamp when the settlement was created in UTC","example":"2026-01-03T14:30:00Z"}},"description":"Result of a cash settlement reconciliation operation"},"SettlementJournalEntryDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID of the journal entry","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"linkedPairId":{"type":"string","description":"Links debit and credit entries that form a balanced posting pair","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"accountCode":{"type":"string","description":"Account code for this entry","example":"1200"},"accountName":{"type":"string","description":"Account name for this entry","example":"Accounts Receivable - ACME Corp - USD"},"currency":{"type":"string","description":"Currency code","example":"USD"},"amount":{"type":"number","description":"Amount (positive for debit, negative for credit)","example":1037.46},"description":{"type":"string","description":"Description of the entry","example":"Settlement clearing for AR account"},"valueDate":{"type":"string","description":"Value date of the transaction","example":"2025-12-20"},"actualSettlementDate":{"type":"string","description":"Actual settlement date when cash actually moved","example":"2025-12-21"}},"description":"Journal entry created during settlement"},"SecretCacheStatusDTO":{"type":"object","properties":{"name":{"type":"string","description":"Secret name in AWS Secrets Manager","example":"currencyguard/ice"},"cached":{"type":"boolean","description":"Whether a cached copy currently exists in Redis. False means this deployment has never successfully read the secret — any vendor using it is running on its property fallback.","example":true},"cachedAt":{"type":"string","description":"When the cached copy was last written, ISO 8601 UTC. Null if never fetched. There is no expiry, so this is also the age of the credential in use.","example":"2026-09-18T09:42:11Z"},"keyNames":{"type":"array","description":"Names of the fields the secret holds, sorted. Values are never returned.","example":["api.password","api.username"],"items":{"type":"string","description":"Names of the fields the secret holds, sorted. Values are never returned.","example":"[\"api.password\",\"api.username\"]"}}},"description":"Cache state for a single managed secret. Contains key names only, never values."},"AuthCallbackResponseDTO":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}},"RegulatedEntityDTOCreate":{"type":"object","properties":{"entityReferenceCode":{"pattern":"^[A-Z0-9]{2}$","type":"string","description":"Two-character code identifying this regulated entity in customer-facing references, e.g. the 'SP' in Guard reference GSP1000104. Immutable once a Guard has been issued under it.","example":"SP"},"piiData":{"$ref":"#/components/schemas/RegulatedEntityDTOCreatePiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this regulated entity's staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000001"},"authSubdomain":{"type":"string","description":"Optional DNS label for the entity's hosted-UI domain. Blank derives an opaque default from the entity id; a value here is published in DNS and CT logs and cannot be changed later.","example":"psp-a7f3c2"},"totpIssuer":{"type":"string","description":"Optional name shown in authenticator apps for this entity's users. Blank uses the environment default (CurrencyGuard).","example":"ScioPay"}},"description":"Regulated entity data to create"},"PaymentDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this payment","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"endToEndId":{"type":"string","description":"ISO 20022 EndToEndId; also the rail idempotency key","example":"CGP-GSP1000104-01"},"direction":{"type":"string","description":"Which way the money moves","example":"PAY_OUT"},"paymentStatus":{"type":"string","description":"Where this payment is in its lifecycle","example":"SETTLED"},"previousAttemptId":{"type":"string","description":"The attempt this payment replaces, if it is a retry","format":"uuid"},"raisedForObligationId":{"type":"string","description":"The obligation this payment was raised to settle; null for a netted or ad-hoc payment","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"recordOrigin":{"type":"string","description":"How this payment came into existence","example":"TRADING"},"counterpartyId":{"type":"string","description":"Counterparty paid, or paying us","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"regulatedEntityId":{"type":"string","description":"PSP whose business this payment is; null means CurrencyGuard's own book","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"paymentCurrency":{"type":"string","description":"ISO 4217 currency of the movement","example":"GBP"},"instructedAmount":{"type":"number","description":"Amount instructed","example":8432},"valueDate":{"type":"string","description":"When the cash is due to move","example":"2026-09-15T00:00:00Z"},"advisedAmount":{"type":"number","description":"Amount the rail advised","example":8432},"advisedAt":{"type":"string","description":"When the advice arrived","example":"2026-09-15T10:04:00Z"},"advisedSource":{"type":"string","description":"Where the advised amount came from","example":"ADVICE"},"confirmedAmount":{"type":"number","description":"Amount the statement confirmed","example":8429},"confirmedAt":{"type":"string","description":"When the statement confirmed it","example":"2026-09-16T06:00:00Z"},"confirmedSource":{"type":"string","description":"Where the confirmed amount came from","example":"STATEMENT"},"rail":{"type":"string","description":"Which rail carries it","example":"TRANSFERMATE"},"idempotencyKey":{"type":"string","description":"Idempotency key presented to the rail","example":"cgp-4f9a1c2e"},"externalRailReference":{"type":"string","description":"The rail's own identifier for this transfer","example":"TM-8837211"},"creditorRailReference":{"type":"string","description":"The rail's beneficiary identifier this instruction names","example":"TM-BEN-448210"},"creditorName":{"type":"string","description":"Beneficiary name as instructed","example":"CurrencyGuard Ltd"},"creditorAccountIdentifier":{"type":"string","description":"The rail's primary account identifier, in whatever form it uses","example":"GB29NWBK60161331926819"},"creditorDetails":{"$ref":"#/components/schemas/PaymentDTOCreditorDetails"},"ultimateDebtorRailReference":{"type":"string","description":"The rail's ultimate-debtor identifier, when one is declared","example":"TM-UD-90881"},"makerUserId":{"type":"string","description":"User who raised this payment","format":"uuid","example":"9c7593b4-0782-470a-b3b6-e5b446db7e3c"},"checkerUserId":{"type":"string","description":"User who approved it","format":"uuid","example":"2b1f7d18-4c1a-4f52-b6b0-3d5f9a2e1c77"},"approvedAt":{"type":"string","description":"When it was approved","example":"2026-09-14T16:20:00Z"},"statusReason":{"type":"string","description":"Why it is in its current status, for rejections and failures"},"eventSequence":{"type":"integer","description":"This row's position in the payment event stream","format":"int64","example":8103},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Payment"},"PaymentRejectionDTO":{"required":["note"],"type":"object","properties":{"note":{"type":"string","description":"Why it is rejected","example":"Wrong beneficiary account"}},"description":"Reject a payment awaiting approval"},"PaymentEventSubscriptionDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this internal subscription","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"streamName":{"maxLength":50,"minLength":0,"type":"string","description":"The feed this subscriber consumes.","example":"payment","enum":["payment"]},"subscriberName":{"maxLength":100,"minLength":0,"type":"string","description":"Name of the consuming processor. Matches its event checkpoint processor_name.","example":"LedgerPaymentFeedConsumer"},"callbackUrl":{"maxLength":500,"minLength":0,"type":"string","description":"Endpoint to which signed event batches are POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/payment"},"signingSecret":{"maxLength":256,"minLength":0,"type":"string","description":"HMAC-SHA256 signing secret for batch payloads. Redacted from responses after creation."},"authMode":{"type":"string","description":"How we authenticate to this subscriber's endpoint. BEARER_AND_HMAC for an endpoint inside the platform's trust boundary; HMAC_ONLY for one outside it, which verifies us by signature alone.","example":"BEARER_AND_HMAC","enum":["BEARER_AND_HMAC","HMAC_ONLY"]},"status":{"type":"string","description":"Status of this subscription","example":"ACTIVE","enum":["ACTIVE","PAUSED","DISABLED","DELETED"]},"lastEventSequence":{"type":"integer","description":"Highest event sequence the subscriber has confirmed it committed. A resume hint, not the source of truth. -1 means nothing delivered yet.","format":"int64","example":1180},"maxBatchSize":{"type":"integer","description":"Maximum number of events the dispatcher will put in one batch","format":"int32","example":100},"eventTypes":{"$ref":"#/components/schemas/PaymentEventSubscriptionDTOEventTypes"},"consecutiveFailures":{"type":"integer","description":"Number of consecutive delivery failures. Reset to 0 on success; subscription auto-pauses when the configured threshold is reached.","format":"int32","example":0},"lastPushAt":{"type":"string","description":"Timestamp of the most recent delivery attempt in UTC","example":"2026-05-30T14:23:01Z"},"lastPushStatus":{"type":"integer","description":"HTTP status code returned by the most recent delivery attempt","format":"int32","example":200},"lastErrorMessage":{"maxLength":500,"minLength":0,"type":"string","description":"Error message from the most recent failed delivery attempt","example":"Connection timed out after 10s"},"pausedAt":{"type":"string","description":"Timestamp when this subscription was paused (auto or manual) in UTC","example":"2026-05-30T14:23:01Z"},"lastRenewedAt":{"type":"string","description":"Timestamp of the subscriber's most recent registration renewal in UTC. Liveness signal.","example":"2026-05-30T14:23:01Z"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a EventSubscription"},"Request":{"required":["buyCurrency","railInstanceId","sellCurrency"],"type":"object","properties":{"railInstanceId":{"type":"string","description":"The rail to convert on","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"fromAccountId":{"type":"string","description":"The wallet being sold out of","example":"743467"},"toAccountId":{"type":"string","description":"The wallet being bought into","example":"743468"},"sellCurrency":{"type":"string","description":"ISO 4217 currency being sold","example":"USD"},"buyCurrency":{"type":"string","description":"ISO 4217 currency being bought","example":"GBP"},"sellAmount":{"type":"number","description":"Amount to sell, when the sell side is fixed","example":50000},"buyAmount":{"type":"number","description":"Amount to end up with, when the buy side is fixed","example":36495},"railQuoteId":{"type":"string","description":"The quote to execute, where the rail issues one"},"idempotencyKey":{"type":"string","description":"Unique per attempt; re-send the same value to retry safely"},"reference":{"type":"string","description":"The settlement this conversion funds, so it can be found again","example":"GSP0000014"}},"description":"Ask what a conversion would cost, or carry one out"},"Quote":{"type":"object","properties":{"railQuoteId":{"type":"string","description":"The rail's handle on this price, where it issues one. Null means the rail re-prices at execution and this quote is an estimate","example":"null"},"rate":{"type":"number","description":"The rate quoted","example":1.37005},"sellCurrency":{"type":"string"},"sellAmount":{"type":"number"},"buyCurrency":{"type":"string"},"buyAmount":{"type":"number"},"expiresAt":{"type":"string","description":"When this price dies","example":"2026-09-28T13:11:42Z"},"binding":{"type":"boolean","description":"Whether the rail will honour this price, or merely re-price near it","example":false}},"description":"What a conversion would cost, and how long the price stands"},"Result":{"type":"object","properties":{"railReference":{"type":"string","description":"The rail's own id for it","example":"T17998944"},"state":{"type":"string","description":"PENDING, COMPLETED, CANCELLED, REVERSED or UNKNOWN","example":"COMPLETED"},"rate":{"type":"number","description":"The rate struck, where the rail reports one","example":1.37005},"sellCurrency":{"type":"string"},"soldAmount":{"type":"number"},"buyCurrency":{"type":"string"},"boughtAmount":{"type":"number"},"batchReference":{"type":"string","description":"Groups conversions raised together, where the rail batches","example":"B3531029"}},"description":"A conversion as the rail reported it"},"RailStatementDTO":{"type":"object","properties":{"railInstanceId":{"type":"string","description":"The rail instance this activity belongs to","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"currency":{"type":"string","description":"Narrowed to this currency, when given","example":"GBP"},"from":{"type":"string","description":"Start of the period, inclusive","example":"2026-05-14T00:00:00Z"},"to":{"type":"string","description":"End of the period, inclusive","example":"2026-09-27T00:00:00Z"},"asOf":{"type":"string","description":"When this was read","example":"2026-09-27T14:31:00Z"},"accountReference":{"type":"string","description":"The rail's own account identifier this activity belongs to","example":"SIM-GBP"},"source":{"type":"string","description":"PULLED where we asked the rail for the period, SUPPLIED where somebody uploaded a document","example":"PULLED"},"openingBalance":{"type":"number","description":"Balance at the start of the period, null where the rail proves none","example":100000},"closingBalance":{"type":"number","description":"Balance at the end of the period, null where the rail proves none","example":86338.98},"complete":{"type":"boolean","description":"Whether opening + settled lines lands on closing. Null means unprovable — this rail reports no balances — which is NOT the same answer as false","example":true},"lines":{"type":"array","items":{"$ref":"#/components/schemas/RailStatementLineDTO"}}},"description":"One rail instance's account activity for a period, read live"},"RailStatementLineDTO":{"type":"object","properties":{"transactionId":{"type":"string","description":"The rail's own identifier for this line","example":"T18170057"},"bookedAt":{"type":"string","description":"When the rail booked this line","example":"2026-09-04T00:00:00Z"},"currency":{"type":"string","description":"ISO 4217 currency of this line","example":"GBP"},"debit":{"type":"number","description":"Money leaving the account on this line, null if this line is a credit","example":13661.02},"credit":{"type":"number","description":"Money arriving on the account on this line, null if this line is a debit"},"beneficiary":{"type":"string","description":"Who was paid, where this line is a debit","example":"UK Payroll GBP"},"payer":{"type":"string","description":"Who paid in, where this line is a credit","example":"Northwind Payroll"},"reference":{"type":"string","description":"Our own reference, where the rail carries one back","example":"CGP-mtnbuswo"},"description":{"type":"string"},"status":{"type":"string","description":"The rail's own status vocabulary for this line","example":"Paid"},"settlement":{"type":"string"},"movementType":{"type":"string"},"batchReference":{"type":"string","description":"Groups several lines raised together, where the rail supports batching","example":"B3535066"},"rawAttributes":{"type":"object","additionalProperties":{"type":"object","description":"The rail's raw record for this line, exactly as received — for diagnosis only, not a stable contract"},"description":"The rail's raw record for this line, exactly as received — for diagnosis only, not a stable contract"}},"description":"One line of account activity"},"WalletBalanceDTO":{"type":"object","properties":{"railAccountId":{"type":"string","description":"The rail's own account identifier","example":"TM-GA-4471"},"accountLabel":{"type":"string","description":"The rail's label for the account","example":"TransferMate GBP"},"currencyCode":{"type":"string","description":"ISO 4217 currency code","example":"GBP"},"total":{"type":"number","description":"The whole balance","example":250000},"available":{"type":"number","description":"Spendable now; null where the rail does not distinguish","example":248000},"reserved":{"type":"number","description":"Held against pending activity; null where the rail does not distinguish","example":2000}},"description":"What one account holds in one currency"},"ObligationWriteOffRequestDTO":{"required":["amount","reason"],"type":"object","properties":{"amount":{"type":"number","description":"Amount to write off, in the obligation's currency. Positive writes off, negative reverses","example":200},"reason":{"type":"string","description":"Why the debt is being written off","example":"Customer short-paid; below collection threshold"}},"description":"Write off part or all of a receivable; a negative amount reverses an earlier write-off"},"PaymentObligationDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this obligation","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"obligationSide":{"type":"string","description":"Which side of the books this debt sits on","example":"RECEIVABLE"},"obligationSource":{"type":"string","description":"What gave rise to the debt","example":"GUARD_FEE"},"obligationInstruction":{"type":"string","description":"Who instructs the settlement, and whose credentials it is instructed with","example":"INSTRUCT_AS_CUSTOMER"},"counterpartyId":{"type":"string","description":"Counterparty that owes, or is owed","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"companyId":{"type":"string","description":"Company the debt belongs to, whose rail credentials settle it","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"regulatedEntityId":{"type":"string","description":"PSP whose business this debt is; null means CurrencyGuard's own book","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"customerId":{"type":"string","description":"The individual who bought the Guard this debt arises from","format":"uuid","example":"9c7593b4-0782-470a-b3b6-e5b446db7e3c"},"obligationCurrency":{"type":"string","description":"ISO 4217 currency of the debt","example":"GBP"},"obligationAmount":{"type":"number","description":"Amount owed","example":2000},"obligationDueDate":{"type":"string","description":"When the cash is due to move","example":"2026-10-15T00:00:00Z"},"obligationStatus":{"type":"string","description":"Open until cleared by payment","example":"OPEN"},"isDisputed":{"type":"boolean","description":"Excluded from automatic payment and netting while disputed","example":false},"disputeReason":{"type":"string","description":"Why the obligation is disputed"},"obligationBatchId":{"type":"string","description":"Monthly netting run this obligation was swept into","format":"uuid"},"recordOrigin":{"type":"string","description":"How this obligation came into existence","example":"TRADING"},"tradeEventSequence":{"type":"integer","description":"INBOUND provenance — sequence of the cgt trade event that raised this","format":"int64","example":4711},"eventSequence":{"type":"integer","description":"OUTBOUND — this row's position in the payment event stream","format":"int64","example":8102},"sourceEntityId":{"type":"string","description":"The cgt entity that gave rise to it (guard, settlement, option trade)","example":"GSP1000104-E01"},"creditorReference":{"type":"string","description":"ISO 11649 RF Creditor Reference the payer quotes for this debt","example":"RF62G01100010401"},"raisedBy":{"type":"string","description":"User who raised this obligation, when manually entered","format":"uuid","example":"9c7593b4-0782-470a-b3b6-e5b446db7e3c"},"originStatementLineId":{"type":"string","description":"Statement line that gave rise to this, when reconciliation-derived","format":"uuid"},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"offsetAccountCode":{"type":"string","description":"MANUAL only: ledger account the debt books against (income or expense)","example":"4900"},"manualReason":{"type":"string","description":"MANUAL only: why the debt was raised by hand","example":"Reissued confirmation fee agreed with PSP"},"originalGuardId":{"type":"string","description":"The Guard lineage this debt belongs to; null for manual debts and standalone options","example":"GSP1000104"}},"description":"Schema for representing a PaymentObligation"},"ObligationReprocessLineDTO":{"type":"object","properties":{"current":{"$ref":"#/components/schemas/PaymentObligationDTO"},"eventSequence":{"type":"integer","description":"The trade event this obligation was (or would be) raised from","format":"int64","example":701},"ruleName":{"type":"string","description":"The rule that produced the recomputed obligation","example":"Guard Fee Receivable"},"recomputedAmount":{"type":"number","description":"The amount the current rules would raise; null when the rules no longer raise it","example":1200},"recomputedSide":{"type":"string","description":"The side the current rules would raise","example":"RECEIVABLE"},"verdict":{"type":"string","description":"UNCHANGED | WILL_REPLACE | WILL_CANCEL | NEW | REVIEW_DIFFERENCE | REVIEW_OVERPAID","example":"UNCHANGED"},"touched":{"type":"boolean","description":"Whether money has moved against this debt (paid, batched or part-cleared)","example":false}},"description":"One obligation's reconciliation in a reprocess preview"},"ObligationReprocessPreviewDTO":{"type":"object","properties":{"guardId":{"type":"string","description":"The Guard whose obligations were reconciled","example":"GIX1000001"},"unchanged":{"type":"integer","description":"Obligations whose recompute matches what exists — nothing to do","format":"int64","example":2},"willReplace":{"type":"integer","description":"Untouched obligations that would be replaced or cancelled","format":"int64","example":1},"needsReview":{"type":"integer","description":"Obligations whose difference a person must decide on (touched, or newly raised)","format":"int64","example":1},"lines":{"type":"array","description":"One line per obligation reconciled","items":{"$ref":"#/components/schemas/ObligationReprocessLineDTO"}}},"description":"Read-only preview of reprocessing one Guard's payment obligations"},"ManualObligationRequestDTO":{"required":["amount","counterpartyId","currency","dueDate","obligationSide","reason"],"type":"object","properties":{"obligationSide":{"type":"string","description":"RECEIVABLE (owed to us) or PAYABLE (owed by us)","example":"RECEIVABLE"},"counterpartyId":{"type":"string","description":"Counterparty who owes, or is owed","format":"uuid"},"regulatedEntityId":{"type":"string","description":"PSP whose business this is; omit for CurrencyGuard's own book","format":"uuid"},"currency":{"type":"string","description":"ISO 4217 currency","example":"GBP"},"amount":{"type":"number","description":"Amount owed, positive","example":500},"dueDate":{"type":"string","description":"When the cash is due, midnight UTC","format":"date-time","example":"2026-10-31T00:00:00Z"},"offsetAccountCode":{"type":"string","description":"Ledger income/expense account it books against; defaults to 4900 Other Income for a receivable, 5900 Other Expense for a payable","example":"4900"},"reason":{"type":"string","description":"Why the debt is being raised by hand","example":"Reissued confirmation fee agreed with PSP"}},"description":"Raise a debt by hand against a counterparty"},"OnboardingEventSubscriptionDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this internal subscription","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"streamName":{"maxLength":50,"minLength":0,"type":"string","description":"The feed this subscriber consumes.","example":"onboarding","enum":["onboarding"]},"subscriberName":{"maxLength":100,"minLength":0,"type":"string","description":"Name of the consuming processor. Matches its event checkpoint processor_name.","example":"LedgerOnboardingFeedConsumer"},"callbackUrl":{"maxLength":500,"minLength":0,"type":"string","description":"Endpoint to which signed event batches are POSTed","example":"http://localhost:8080/api-internal/v1/ledger/webhook-deliveries/onboarding"},"authMode":{"type":"string","description":"How we authenticate to this subscriber's endpoint. BEARER_AND_HMAC for an endpoint inside the platform's trust boundary; HMAC_ONLY for one outside it, which verifies us by signature alone.","example":"BEARER_AND_HMAC","enum":["BEARER_AND_HMAC","HMAC_ONLY"]},"status":{"type":"string","description":"Status of this subscription","example":"ACTIVE","enum":["ACTIVE","PAUSED","DISABLED","DELETED"]},"lastEventSequence":{"type":"integer","description":"Highest event sequence the subscriber has confirmed it committed. A resume hint, not the source of truth. -1 means nothing delivered yet.","format":"int64","example":1180},"maxBatchSize":{"type":"integer","description":"Maximum number of events the dispatcher will put in one batch","format":"int32","example":100},"eventTypes":{"$ref":"#/components/schemas/OnboardingEventSubscriptionDTOEventTypes"},"consecutiveFailures":{"type":"integer","description":"Number of consecutive delivery failures. Reset to 0 on success; subscription auto-pauses when the configured threshold is reached.","format":"int32","example":0},"lastPushAt":{"type":"string","description":"Timestamp of the most recent delivery attempt in UTC","example":"2026-05-30T14:23:01Z"},"lastPushStatus":{"type":"integer","description":"HTTP status code returned by the most recent delivery attempt","format":"int32","example":200},"lastErrorMessage":{"maxLength":500,"minLength":0,"type":"string","description":"Error message from the most recent failed delivery attempt","example":"Connection timed out after 10s"},"pausedAt":{"type":"string","description":"Timestamp when this subscription was paused (auto or manual) in UTC","example":"2026-05-30T14:23:01Z"},"lastRenewedAt":{"type":"string","description":"Timestamp of the subscriber's most recent registration renewal in UTC. Liveness signal.","example":"2026-05-30T14:23:01Z"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a EventSubscription"},"NetDaniaStatusResponseDTO":{"type":"object","properties":{"lastSuccessfulPoll":{"type":"string"},"lastSkipReason":{"type":"string"},"healthStatus":{"type":"string"},"message":{"type":"string"}}},"ManualJournalEntryDTOCreate":{"required":["amount","creditAccountCode","currency","debitAccountCode","description"],"type":"object","properties":{"description":{"maxLength":500,"minLength":10,"type":"string","description":"Description of the journal entry purpose","example":"Correction to Q4 FX gain on GBPUSD hedge"},"tradeDate":{"type":"string","description":"Trade date in ISO 8601 date format (yyyy-MM-dd). Required if valueDate is provided. Omit both tradeDate and valueDate for cash-basis entries (actualSettlementDate only).","example":"2025-12-18"},"valueDate":{"type":"string","description":"Value date in ISO 8601 date format (yyyy-MM-dd). Required if tradeDate is provided. Omit both tradeDate and valueDate for cash-basis entries (actualSettlementDate only).","example":"2025-12-20"},"actualSettlementDate":{"type":"string","description":"Actual settlement date in ISO 8601 date format (yyyy-MM-dd). Used for three-basis accounting to record when cash actually moved. Can be provided alone for cash-basis entries, or with tradeDate and valueDate for forecast-basis entries.","example":"2025-12-22"},"debitAccountCode":{"type":"string","description":"Account code to debit","example":"1010"},"creditAccountCode":{"type":"string","description":"Account code to credit","example":"4200"},"amount":{"minimum":1e-8,"exclusiveMinimum":false,"type":"number","description":"Amount to transfer (always positive)","example":1000},"currency":{"type":"string","description":"ISO 4217 currency code","example":"USD"}},"description":"Request to create a manual journal entry (debit/credit pair)"},"JournalEntryDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this journalEntry row","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"linkedPairId":{"type":"string","description":"Links debit and credit entries that form a balanced posting pair","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"eventSource":{"type":"string","description":"The event counter event_sequence belongs to. MANUAL for operator-entered journals.","example":"TRADING"},"eventSequence":{"type":"integer","description":"Event sequence number that triggered this journalEntry entry (NULL for manual entries). Only meaningful together with event_source.","format":"int64","example":1},"tradeDate":{"type":"string","description":"Trade date of the transaction (NULL for settlement journals imported from broker statements)","example":"2025-12-05"},"valueDate":{"type":"string","description":"Value date of the transaction (NULL for settlement journals imported from broker statements)","example":"2025-12-09"},"actualSettlementDate":{"type":"string","description":"Actual settlement date when cash actually moved (NULL if not yet settled, set for settlement journals)","example":"2025-12-09"},"accountCode":{"type":"string","description":"Account code for this journalEntry entry","example":"1200"},"accountCodeAccountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"currency":{"type":"string","description":"Currency code for this journalEntry entry","example":"USD"},"amount":{"type":"number","description":"Amount for this journalEntry entry (positive for debit, negative for credit)","example":1037.46},"description":{"type":"string","description":"Description of this journalEntry entry","example":"Receivable from counterparty for option premium"},"ruleVersion":{"type":"string","description":"Rule version that created this journalEntry entry (NULL for manual entries)","example":"JERv1"},"ref1":{"type":"string","description":"Correlation slot 1 — the regulated entity","example":"f7a07785-edbb-48f8-9c6a-df6a7ac38d1d"},"ref2":{"type":"string","description":"Correlation slot 2 — the counterparty","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"ref3":{"type":"string","description":"Correlation slot 3 — the Guard lineage reference (Guard/GuardSettlement/FXOptionTrade) or the trade (FXTrade)","example":"G011000104"},"ref4":{"type":"string","description":"Correlation slot 4 — the payment or remittance reference (CGP reference, RF creditor reference, or the rail's own)","example":"CGP-GSP1000104-01"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a JournalEntry"},"JournalEntryEventBatchReversalDTOCreate":{"required":["eventSequences","eventSource","reason","valueDate"],"type":"object","properties":{"eventSource":{"type":"string","description":"The counter the event sequence(s) belong to. Required: a sequence number selects nothing on its own, because every producing schema owns its own counter and all of them start at 1. Only sources that post journals are reversible this way.","example":"TRADING","enum":["TRADING","PAYMENT","ONBOARDING","MANUAL","TRADING","PAYMENT"]},"eventSequences":{"type":"array","description":"List of event sequence numbers to reverse","example":[2,5,9],"items":{"type":"integer","description":"List of event sequence numbers to reverse","format":"int64"}},"reason":{"maxLength":500,"minLength":10,"type":"string","description":"Reason for the reversals","example":"Specific trade corrections"},"valueDate":{"type":"string","description":"Reversal date in ISO 8601 date format (yyyy-MM-dd)","example":"2025-12-18"}},"description":"Request to reverse journal entries by specific event sequence IDs"},"JournalEntryReversalDTOCreate":{"required":["reason","valueDate"],"type":"object","properties":{"eventSource":{"type":"string","description":"The counter the event sequence belongs to. Required when reversing by event sequence, ignored when reversing by linkedPairId. A sequence number selects nothing on its own, because every producing schema owns its own counter and all of them start at 1.","example":"TRADING","enum":["TRADING","PAYMENT","ONBOARDING","MANUAL","TRADING","PAYMENT"]},"reason":{"maxLength":500,"minLength":10,"type":"string","description":"Reason for the reversal (will be appended to automatic description)","example":"Trade cancelled due to settlement failure"},"valueDate":{"type":"string","description":"Value date when the reversal takes effect in ISO 8601 date format (yyyy-MM-dd). Must be >= today and a valid business date for the currency.","example":"2025-12-22"}},"description":"Request to reverse a journal entry"},"JournalEntryEventRangeReversalDTOCreate":{"required":["eventSequenceFrom","eventSequenceTo","eventSource","reason","valueDate"],"type":"object","properties":{"eventSource":{"type":"string","description":"The counter the event sequence(s) belong to. Required: a sequence number selects nothing on its own, because every producing schema owns its own counter and all of them start at 1. Only sources that post journals are reversible this way.","example":"TRADING","enum":["TRADING","PAYMENT","ONBOARDING","MANUAL","TRADING","PAYMENT"]},"eventSequenceFrom":{"type":"integer","description":"Starting event sequence number (inclusive)","format":"int64","example":100},"eventSequenceTo":{"type":"integer","description":"Ending event sequence number (inclusive)","format":"int64","example":150},"reason":{"maxLength":500,"minLength":10,"type":"string","description":"Reason for the reversals","example":"Batch processing error correction"},"valueDate":{"type":"string","description":"Reversal date in ISO 8601 date format (yyyy-MM-dd)","example":"2025-12-18"}},"description":"Request to reverse journal entries by event sequence range"},"JournalEntryBatchReversalDTOCreate":{"required":["linkedPairIds","reason","valueDate"],"type":"object","properties":{"linkedPairIds":{"type":"array","description":"List of linkedPairIds (each identifies a complete debit/credit pair)","example":["123e4567-e89b-12d3-a456-426614174000","223e4567-e89b-12d3-a456-426614174001"],"items":{"type":"string","description":"List of linkedPairIds (each identifies a complete debit/credit pair)","format":"uuid"}},"reason":{"maxLength":500,"minLength":10,"type":"string","description":"Reason for the reversals","example":"Period close correction"},"valueDate":{"type":"string","description":"Value date when the reversal takes effect in ISO 8601 date format (yyyy-MM-dd). Must be >= today and a valid business date for the currency.","example":"2025-12-22"}},"description":"Request to reverse multiple journal entry pairs by linkedPairId"},"ManualJournalEntryBatchDTOCreate":{"required":["entries"],"type":"object","properties":{"entries":{"type":"array","description":"List of manual journal entries to create","items":{"$ref":"#/components/schemas/ManualJournalEntryDTOCreate"}}},"description":"Request to create a batch of manual journal entries"},"CreateRegulatedUserInvitationByInternalUserDTO":{"required":["email","firstName","lastName","regulatedEntityId"],"type":"object","properties":{"email":{"maxLength":100,"minLength":0,"type":"string","description":"Email address of the person being invited","example":"sales.rep@regulatedentity.com"},"firstName":{"maxLength":50,"minLength":0,"type":"string","description":"First name of the person being invited","example":"Jane"},"lastName":{"maxLength":50,"minLength":0,"type":"string","description":"Last name of the person being invited","example":"Smith"},"regulatedEntityId":{"type":"string","description":"The regulated entity ID the regulated user will belong to","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"message":{"maxLength":2000,"minLength":0,"type":"string","description":"Optional welcome message for the invitation","example":"Welcome to your regulated entity! Please complete your onboarding."},"entitlementsTemplateName":{"maxLength":100,"minLength":0,"type":"string","description":"Entitlements template name to assign to the invited user","example":"Regulated User"}},"description":"Request to create a regulated user invitation"},"CreateInternalInvitationByInternalUserDTO":{"required":["email","firstName","lastName"],"type":"object","properties":{"email":{"maxLength":100,"minLength":0,"type":"string","description":"Email address of the person being invited","example":"john.doe@currencyguard.com"},"firstName":{"maxLength":50,"minLength":0,"type":"string","description":"First name of the person being invited","example":"John"},"lastName":{"maxLength":50,"minLength":0,"type":"string","description":"Last name of the person being invited","example":"Doe"},"message":{"maxLength":2000,"minLength":0,"type":"string","description":"Optional welcome message for the invitation","example":"Welcome to CurrencyGuard! Please complete your onboarding."},"entitlementsTemplateName":{"maxLength":100,"minLength":0,"type":"string","description":"Entitlements template name to assign to the invited user","example":"CurrencyGuard Administrator"}},"description":"Request to create an internal user invitation"},"RestartResponse":{"type":"object","properties":{"sourceName":{"type":"string"},"status":{"type":"string"},"isActive":{"type":"boolean"},"configurationApplied":{"type":"boolean"},"message":{"type":"string"}}},"SwitchResponseDTO":{"type":"object","properties":{"instrument":{"type":"string"},"activeSource":{"type":"string"},"manualOverride":{"type":"boolean"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"ICEStatusResponseDTO":{"type":"object","properties":{"lastSuccessfulPoll":{"type":"string"},"lastSkipReason":{"type":"string"},"healthStatus":{"type":"string"},"message":{"type":"string"}}},"VoidGuardRequestDTO":{"type":"object","properties":{"reason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for voiding the guard (optional)","example":"Fee not received by deadline, PSP unresponsive"}},"description":"Request to void a guard whose fee was never received"},"VoidGuardResponseDTO":{"type":"object","properties":{"guard":{"$ref":"#/components/schemas/GuardDTOInternal"},"settlementId":{"type":"string","description":"ID of the guard settlement record created for this void","example":"e1f2d3c4-b5a6-7890-9c8d-7e6f5d4c3b2a"}},"description":"Guard void response — fee not received by deadline, hedge unwound"},"ExecuteGuardRequestDTO":{"required":["clientConversionAmount","conversionRate","foreignAmount","foreignCurrency","guardCurrency"],"type":"object","properties":{"foreignAmount":{"type":"number"},"foreignCurrency":{"type":"string"},"guardCurrency":{"type":"string"},"conversionRate":{"type":"number"},"clientConversionAmount":{"type":"number","description":"What this tranche would cost the client at their own all-in rate. Required on every settlement."}}},"RequestFundedSettlementDTO":{"required":["foreignAmount"],"type":"object","properties":{"foreignAmount":{"type":"number"}}},"RejectSettlementRequestDTO":{"required":["reason"],"type":"object","properties":{"reason":{"type":"string"}}},"ExecuteFundedSettlementRequestDTO":{"required":["boughtAmount","buyCurrency","railReference","sellCurrency","soldAmount"],"type":"object","properties":{"railReference":{"type":"string","description":"The rail's own reference for the conversion","example":"T17998944"},"sellCurrency":{"type":"string","description":"Currency sold","example":"USD"},"soldAmount":{"type":"number","description":"Amount sold, as the rail confirmed it","example":136010},"buyCurrency":{"type":"string","description":"Currency bought","example":"GBP"},"boughtAmount":{"type":"number","description":"Amount bought, as the rail confirmed it","example":99491.79}},"description":"The rail conversion a funded settlement is executed against"},"ConvertAndExecuteRequestDTO":{"type":"object","properties":{"railQuoteId":{"type":"string","description":"The rail's quote id from the conversion preview, where the rail issues one"}},"description":"Convert and execute a funded settlement"},"ConvertAndExecuteResultDTO":{"type":"object","properties":{"settlement":{"$ref":"#/components/schemas/GuardSettlementDTOInternal"},"conversion":{"$ref":"#/components/schemas/SettlementConversionDTO"},"convertedNow":{"type":"boolean","description":"True if this call converted; false if it found a conversion already made for the settlement"}},"description":"A funded settlement converted on the rail and executed"},"SettlementConversionDTO":{"type":"object","properties":{"railReference":{"type":"string","description":"The rail's own reference for the conversion","example":"T17998944"},"state":{"type":"string","description":"The rail's state; absent on a rail that settles immediately","example":"COMPLETED"},"rate":{"type":"number","description":"The rate on the traded pair's convention (quote per base)","example":1.3670475},"sellCurrency":{"type":"string","description":"Currency sold","example":"USD"},"soldAmount":{"type":"number","description":"Amount sold","example":136704.75},"buyCurrency":{"type":"string","description":"Currency bought","example":"GBP"},"boughtAmount":{"type":"number","description":"Amount bought","example":100000}},"description":"A conversion on the regulated entity's rail, as the rail reported it"},"FXOptionPriceOverrideDTO":{"type":"object","properties":{"strike":{"type":"number"},"expiry":{"type":"string"},"premium":{"type":"number"},"premiumCurrency":{"type":"string"},"premiumSettlementAmount":{"type":"number"},"premiumSettlementCurrency":{"type":"string"},"notional":{"type":"number"},"counterpartyId":{"type":"string"},"externalReference":{"maxLength":64,"minLength":0,"type":"string"}}},"CancelFundingRequestDTO":{"type":"object","properties":{"reason":{"type":"string"}}},"ExtensionHedgeConfirmationDTO":{"type":"object","properties":{"settlementHedgeSell":{"$ref":"#/components/schemas/FXOptionPriceOverrideDTO"},"extensionHedgeBuy":{"$ref":"#/components/schemas/FXOptionPriceOverrideDTO"}}},"Line":{"required":["foreignAmount","guardId"],"type":"object","properties":{"guardId":{"type":"string"},"foreignAmount":{"type":"number"}}},"RequestFundedSettlementsDTO":{"required":["settlements"],"type":"object","properties":{"settlements":{"type":"array","items":{"$ref":"#/components/schemas/Line"}}}},"GuardMarginScheduleDTOCreate":{"required":["marginSchedule"],"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"Regulated entity ID for entity-specific schedules. NULL = applies to all entities","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair code for pair-specific schedules. NULL = applies to all currency pairs","example":"GBPUSD"},"marginSchedule":{"$ref":"#/components/schemas/GuardMarginScheduleDTOCreateMarginSchedule"}},"description":"Guard margin schedule creation data"},"FXTradeDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this FX trade","example":"CCG0000001"},"tradeType":{"pattern":"^(SPOT|FORWARD|SWAP)$","type":"string","description":"Type of FX trade","example":"SPOT","enum":["SPOT","FORWARD","SWAP"]},"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"tradeStatus":{"pattern":"^(ACTIVE|CANCELLED)$","type":"string","description":"Status of the FX trade","example":"ACTIVE","enum":["ACTIVE","CANCELLED"]},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this FX trade","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this trade was executed with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the FX trade","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the FX trade","example":"USD"},"tradeDate":{"type":"string","description":"Trade date - the date when the FX trade was executed","example":"2025-01-15T10:30:00Z"},"traderId":{"type":"string","description":"ID of the internalUser managing this FX trade","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"book":{"maxLength":30,"minLength":0,"type":"string","description":"Book this FX trade resides in","example":"FX Trading Book"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing - globally monotonic across all entities","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXTrade"},"FXTradeLegDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this FX trade leg","format":"uuid","example":"456e7890-a12b-34c5-d678-901234567890"},"fxTradeId":{"type":"string","description":"ID of the parent FX trade","example":"CCG0000001"},"legType":{"pattern":"^(SINGLE|NEAR|FAR)$","type":"string","description":"Type of leg in the trade","example":"SINGLE","enum":["SINGLE","NEAR","FAR"]},"buySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Direction of this leg","example":"BUY","enum":["BUY","SELL"]},"amount":{"type":"number","description":"Amount of the leg in the base currency","example":100000},"rate":{"type":"number","description":"FX rate for this leg","example":1.22},"settlementAmount":{"type":"number","description":"Settlement amount in the quote currency (amount × rate). Follows FIX protocol SettlCurrAmt (Tag 119)","example":122000},"valueDate":{"type":"string","description":"Value date - the date when this leg settles","example":"2025-01-17"},"forwardPoints":{"type":"number","description":"Forward points for forward/swap legs (difference from spot rate)","example":0.00123},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"jbloggs24"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXTradeLeg"},"FXTradeWithLegsResponse":{"type":"object","properties":{"trade":{"$ref":"#/components/schemas/FXTradeDTO"},"legs":{"type":"array","description":"The settlement legs for this trade","items":{"$ref":"#/components/schemas/FXTradeLegDTO"}}},"description":"FX trade with associated settlement legs"},"FXTradeDTOUpdate":{"type":"object","properties":{"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this FX trade","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this trade was executed with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the FX trade","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the FX trade","example":"USD"},"legs":{"type":"array","description":"Settlement legs for this FX trade. SPOT/FORWARD trades have 1 leg, SWAP trades have 2 legs (NEAR + FAR)","items":{"$ref":"#/components/schemas/FXTradeLegDTOUpdate"}}},"description":"Schema for representing a FXTrade"},"FXTradeLegDTOUpdate":{"type":"object","properties":{"buySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Direction of this leg","example":"BUY","enum":["BUY","SELL"]},"amount":{"type":"number","description":"Amount of the leg in the base currency","example":100000},"rate":{"type":"number","description":"FX rate for this leg","example":1.22},"settlementAmount":{"type":"number","description":"Settlement amount in the quote currency (amount × rate). Follows FIX protocol SettlCurrAmt (Tag 119)","example":122000},"valueDate":{"type":"string","description":"Value date - the date when this leg settles","example":"2025-01-17"},"forwardPoints":{"type":"number","description":"Forward points for forward/swap legs (difference from spot rate)","example":0.00123}},"description":"Schema for representing a FXTradeLeg"},"FXTradeDTOCreate":{"required":["baseCurrency","legs","quoteCurrency","tradeDate"],"type":"object","properties":{"id":{"type":"string","description":"ID for this FX trade","example":"CCG0000001"},"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this FX trade","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this trade was executed with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the FX trade","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the FX trade","example":"USD"},"tradeDate":{"type":"string","description":"Trade date - the date when the FX trade was executed","example":"2025-01-15T10:30:00Z"},"legs":{"type":"array","description":"Settlement legs for this FX trade. SPOT/FORWARD trades have 1 leg, SWAP trades have 2 legs (NEAR + FAR)","items":{"$ref":"#/components/schemas/FXTradeLegDTOCreate"}}},"description":"Schema for representing a FXTrade"},"FXTradeLegDTOCreate":{"type":"object","properties":{"id":{"type":"string","description":"ID for this FX trade leg","format":"uuid","example":"456e7890-a12b-34c5-d678-901234567890"},"fxTradeId":{"type":"string","description":"ID of the parent FX trade","example":"CCG0000001"},"legType":{"pattern":"^(SINGLE|NEAR|FAR)$","type":"string","description":"Type of leg in the trade","example":"SINGLE","enum":["SINGLE","NEAR","FAR"]},"buySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Direction of this leg","example":"BUY","enum":["BUY","SELL"]},"amount":{"type":"number","description":"Amount of the leg in the base currency","example":100000},"rate":{"type":"number","description":"FX rate for this leg","example":1.22},"settlementAmount":{"type":"number","description":"Settlement amount in the quote currency (amount × rate). Follows FIX protocol SettlCurrAmt (Tag 119)","example":122000},"valueDate":{"type":"string","description":"Value date - the date when this leg settles","example":"2025-01-17"},"forwardPoints":{"type":"number","description":"Forward points for forward/swap legs (difference from spot rate)","example":0.00123}},"description":"Schema for representing a FXTradeLeg"},"FXOptionTradeDTOUpdate":{"type":"object","properties":{"id":{"type":"string","description":"ID for this vanilla FX option. A hedge option reuses its owning Guard/settlement reference with the leading G swapped for O (e.g. OSP1000104-E01); a standalone option is OCG0000001-style.","example":"OSP1000104"},"originalGuardId":{"type":"string","description":"ID of the original guard that this option was created to hedge. Used to track all hedge options across guard extensions.","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this option","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this option was traded with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"tradeDate":{"type":"string","description":"Trade date - the date when the option trade was executed","example":"2025-01-15T10:30:00Z"},"optionBuySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Indicates whether the option is a buy or sell","example":"BUY","enum":["BUY","SELL"]},"optionStatus":{"pattern":"^(PENDING_BUY|PENDING_SELL|BOUGHT|SOLD|PENDING_CANCEL|CANCELLED)$","type":"string","description":"Status of the option","example":"BOUGHT","enum":["PENDING_BUY","PENDING_SELL","BOUGHT","SOLD","PENDING_CANCEL","CANCELLED"]},"optionCallPut":{"pattern":"^(CALL|PUT)$","type":"string","description":"Specifies if the option is a call or put","example":"CALL","enum":["CALL","PUT"]},"strike":{"type":"number","description":"Strike price of the option","example":1.25},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time of trade execution","example":1.25123},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time of trade execution","example":1.25145},"expiryDate":{"type":"string","description":"Date when the option expires","example":"2025-12-31"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the option","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the option","example":"USD"},"notional":{"type":"number","description":"Notional amount of the option in the base currency","example":100000},"premium":{"type":"number","description":"Premium paid for the option","example":5000},"premiumCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is denominated","example":"USD"},"premiumSettlementAmount":{"type":"number","description":"Amount of the premium in the settlement currency","example":5000},"premiumSettlementCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is settled","example":"GBP"},"optionPrice":{"type":"number","description":"Price of the option","example":0.05},"optionStyle":{"pattern":"^(AMERICAN|EUROPEAN)$","type":"string","description":"Style of the option","example":"EUROPEAN","enum":["AMERICAN","EUROPEAN"]},"deliveryMethod":{"pattern":"^(CASH|PHYSICAL)$","type":"string","description":"Delivery method of the option","example":"CASH","enum":["CASH","PHYSICAL"]},"statusReason":{"maxLength":250,"minLength":0,"type":"string","description":"Reason for the option's status","example":"Awaiting approval"},"traderId":{"type":"string","description":"ID of the internalUser managing this option","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"book":{"maxLength":30,"minLength":0,"type":"string","description":"Book this option resides in","example":"Guard Book"}},"description":"Schema for representing a FXOptionTrade"},"FXOptionTradeDTOCreate":{"required":["baseCurrency","expiryDate","notional","quoteCurrency"],"type":"object","properties":{"originalGuardId":{"type":"string","description":"ID of the original guard that this option was created to hedge. Used to track all hedge options across guard extensions.","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"externalReference":{"type":"string","description":"The counterparty venue's own reference for this trade, e.g. Saxo's trade ref","example":"SAXO-4471829"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this option","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty this option was traded with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"tradeDate":{"type":"string","description":"Trade date - the date when the option trade was executed","example":"2025-01-15T10:30:00Z"},"optionBuySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Indicates whether the option is a buy or sell","example":"BUY","enum":["BUY","SELL"]},"optionCallPut":{"pattern":"^(CALL|PUT)$","type":"string","description":"Specifies if the option is a call or put","example":"CALL","enum":["CALL","PUT"]},"strike":{"type":"number","description":"Strike price of the option","example":1.25},"spotFxBid":{"type":"number","description":"Spot FX bid rate at the time of trade execution","example":1.25123},"spotFxAsk":{"type":"number","description":"Spot FX ask rate at the time of trade execution","example":1.25145},"expiryDate":{"type":"string","description":"Date when the option expires","example":"2025-12-31"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency of the option","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency of the option","example":"USD"},"notional":{"type":"number","description":"Notional amount of the option in the base currency","example":100000},"premium":{"type":"number","description":"Premium paid for the option","example":5000},"premiumCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is denominated","example":"USD"},"premiumSettlementAmount":{"type":"number","description":"Amount of the premium in the settlement currency","example":5000},"premiumSettlementCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency in which the premium is settled","example":"GBP"},"optionStyle":{"pattern":"^(AMERICAN|EUROPEAN)$","type":"string","description":"Style of the option","example":"EUROPEAN","enum":["AMERICAN","EUROPEAN"]}},"description":"Schema for representing a FXOptionTrade"},"FXOptionVendorPriceRequestDTO":{"required":["callPut","currencyPair","expiryDate"],"type":"object","properties":{"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair as CurrencyGuard stores it (e.g., GBPUSD)","example":"GBPUSD"},"notional":{"type":"number","description":"Option notional in base currency. Optional: omit it and the vendor prices its own default clip, which the response reports as amountPriced. Not cosmetic either way — a vendor's spread widens with size, so the same option at 100k and at 10m comes back with different premiums.","example":1000000},"expiryDate":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string","description":"Option expiry date in ISO format (YYYY-MM-DD). The vendor sets the delivery date from it — typically two business days later.","example":"2026-12-31"},"callPut":{"pattern":"^(CALL|PUT)$","type":"string","description":"Option type (CALL or PUT)","example":"CALL","enum":["CALL","PUT"]},"strikePrice":{"type":"number","description":"Strike price. Omit for the vendor's own at-the-money — the response reports which strike it actually priced.","example":1.275},"correlationId":{"type":"string","description":"Caller's own identifier for this option, echoed back on the response. Used by a report to join prices back to the Guards that prompted them; never interpreted.","example":"guard-8f2c1b40"}},"description":"Request data for a vendor's price for a vanilla FX option. Unlike scenario pricing, no market data can be overridden — the vendor prices off its own."},"CurrencyAmountDTO":{"type":"object","properties":{"amount":{"type":"number","description":"amount of the CurrencyAmount"},"currency":{"type":"string","description":"currency of the CurrencyAmount","example":"???"}},"description":"Data Transfer Object representing a CurrencyAmount"},"FXOptionVendorPriceDTO":{"type":"object","properties":{"vendor":{"type":"string","description":"Which counterparty quoted this","example":"SAXO"},"currencyPair":{"type":"string","description":"Currency pair as CurrencyGuard stores it","example":"GBPUSD"},"quotedPair":{"type":"string","description":"The instrument the vendor was actually asked about. Differs from currencyPair when CurrencyGuard stores a pair against the inverse of the tradable one — a stored GBPEUR option is quoted as EURGBP. Every rate below, and the premium's denomination, are in THIS convention.","example":"EURGBP"},"quotedInverted":{"type":"boolean","description":"True when quotedPair is the inverse of the stored pair, so the figures below are not in the stored convention. Volatility is identical either way; strike, spot and forward are exact reciprocals; delta and vega are the vendor's own and are NOT converted back, because FX delta is convention-dependent.","example":true},"callPut":{"type":"string","description":"Option type AS QUOTED. A stored GBPEUR call is quoted as an EURGBP put — the same contract named from the other side.","example":"CALL"},"strikePriced":{"type":"number","description":"The strike the vendor actually priced. When the request omitted a strike this is the vendor's own at-the-money, which is the only way to learn what that was.","example":1.275},"amountPriced":{"type":"number","description":"The clip size the quote is for, in base currency. Measured on GBPUSD, Saxo quoted 3.0 pips wide at 1m and 15.2 at 50m — a premium without its clip size cannot be compared with anything.","example":1000000},"expiryDate":{"type":"string","description":"Option expiry, ISO 8601","example":"2026-12-31T00:00:00Z"},"impliedVolatility":{"type":"number","description":"Mid implied volatility as a decimal fraction (0.0544 is 5.44%). The vendor publishes no two-way volatility.","example":0.0544},"delta":{"type":"number","description":"Delta from the option holder's perspective: positive for a call, negative for a put. Same convention as our own pricing, so the two are directly comparable.","example":0.5123},"vega":{"type":"number","description":"Sensitivity of the premium to volatility, in premium units per 1.0 of volatility","example":1234.56},"gamma":{"type":"number","description":"Sensitivity of delta to spot, where the vendor publishes it. Often null — Saxo omits it from the same field group that carries delta and vega.","example":0.0000123},"premiumBid":{"type":"number","description":"Vendor's bid premium for amountPriced, in premiumUnit","example":0.0121},"premiumAsk":{"type":"number","description":"Vendor's ask premium for amountPriced, in premiumUnit","example":0.0129},"premiumBidAmount":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"premiumAskAmount":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"premiumUnit":{"type":"string","description":"What the premium figures are denominated in. Carried rather than assumed: the same number is a rate per unit of base or a cash amount for the whole clip depending on a convention the vendor payload never states, and a caller populating a hedge entry form has to know which it is holding.","example":"QUOTE_CCY_PER_BASE_UNIT"},"forward":{"type":"number","description":"Vendor's forward rate to the option's delivery date, where it published one","example":1.274},"spot":{"type":"number","description":"Vendor's spot at the time of the quote","example":1.2745},"spotDate":{"type":"string","description":"Vendor's spot value date, ISO 8601","example":"2026-09-23T00:00:00Z"},"valueDate":{"type":"string","description":"Vendor's option delivery date — when an exercised option settles, ISO 8601","example":"2027-01-04T00:00:00Z"},"vendorTimestamp":{"type":"string","description":"When the vendor says the quote was last updated, ISO 8601. Null where it gave no genuine one — Saxo answers with a .NET default date for a quote with nothing behind it, and a first-century timestamp on a price screen is worse than none.","example":"2026-09-21T14:30:15Z"}},"description":"A vanilla FX option price as an external vendor quoted it: a single mid volatility and a two-way premium, not a two-sided model valuation."},"FXOptionVendorPriceWithRiskStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXOptionVendorPriceDTO"},"correlationId":{"type":"string","description":"The caller's identifier for the option this answers, echoed from the request. Null when the request did not supply one.","example":"guard-8f2c1b40"}},"description":"A vendor's option price with state metadata. When valid=false the value may still be partially populated — a vendor that will not quote a strike answers with nulls rather than an error."},"FXOptionVendorPriceBatchRequestDTO":{"required":["requests"],"type":"object","properties":{"requests":{"maxItems":100,"minItems":0,"type":"array","description":"The options to price, asked for in this order","items":{"$ref":"#/components/schemas/FXOptionVendorPriceRequestDTO"}}},"description":"A list of options to price with the vendor. Results stream back as they arrive, in request order, each tagged with its correlationId."},"FXOptionScenarioRequestDTO":{"required":["callPut","currencyPair","expiryDate","notional"],"type":"object","properties":{"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair (e.g., EURUSD)","example":"GBPUSD"},"notional":{"type":"number","description":"Option notional amount in base currency","example":100000},"expiryDate":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string","description":"Option expiry date in ISO format (YYYY-MM-DD)","example":"2025-12-31"},"callPut":{"pattern":"^(CALL|PUT)$","type":"string","description":"Option type (CALL or PUT)","example":"CALL","enum":["CALL","PUT"]},"strikePrice":{"type":"number","description":"Strike price (leave blank for ATM)","example":1.275},"customSpotBid":{"type":"number","description":"Custom spot bid rate","example":1.2745},"customSpotAsk":{"type":"number","description":"Custom spot ask rate","example":1.2755},"customVolBid":{"type":"number","description":"Custom bid implied volatility (as decimal, e.g., 0.15 for 15%)","example":0.15},"customVolAsk":{"type":"number","description":"Custom ask implied volatility (as decimal, e.g., 0.16 for 16%)","example":0.16},"customQuoteIRBid":{"type":"number","description":"Custom quote currency bid interest rate (as decimal, e.g., 0.05 for 5%)","example":0.05},"customQuoteIRAsk":{"type":"number","description":"Custom quote currency ask interest rate (as decimal, e.g., 0.051 for 5.1%)","example":0.051},"customBaseIRBid":{"type":"number","description":"Custom base currency bid interest rate (as decimal, e.g., 0.045 for 4.5%)","example":0.045},"customBaseIRAsk":{"type":"number","description":"Custom base currency ask interest rate (as decimal, e.g., 0.046 for 4.6%)","example":0.046},"customForwardBid":{"type":"number","description":"Custom forward bid rate at expiry tenor (outright)","example":1.274},"customForwardAsk":{"type":"number","description":"Custom forward ask rate at expiry tenor (outright)","example":1.276},"customSwapPointsBid":{"type":"number","description":"Custom forward swap points bid (added to spot to get outright forward)","example":-0.001},"customSwapPointsAsk":{"type":"number","description":"Custom forward swap points ask (added to spot to get outright forward)","example":-0.0005},"customValueDate":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string","description":"Custom valuation date (ISO format YYYY-MM-DD)","example":"2025-01-15"}},"description":"Request data for FX option scenario pricing with custom market inputs"},"FXOptionTwoSidedValuationDTO":{"type":"object","properties":{"baseCurrency":{"type":"string","description":"Base currency code (e.g., GBP)","example":"GBP"},"quoteCurrency":{"type":"string","description":"Quote currency code (e.g., USD)","example":"USD"},"callPut":{"type":"string","description":"Option type: CALL or PUT","example":"CALL","enum":["CALL","PUT"]},"strike":{"type":"number","description":"Strike rate as quote currency per base currency","example":1.25},"expiryDate":{"type":"string","description":"Option expiry date and time (ISO8601)","example":"2025-03-15T10:00:00Z"},"settlementDate":{"type":"string","description":"Settlement date (T+2 after expiry, ISO8601)","example":"2025-03-17T00:00:00Z"},"notional":{"type":"number","description":"Notional amount in base currency","example":100000},"optionStyle":{"type":"string","description":"Option style: EUROPEAN or AMERICAN","example":"EUROPEAN"},"marketPrice":{"$ref":"#/components/schemas/FXOptionPriceStateDTO"},"bidMtm":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"bidDelta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"bidVega":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"bidGamma":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"askMtm":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"askDelta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"askVega":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"askGamma":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"midMtm":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"midDelta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"midVega":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"midGamma":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"bidAskSpread":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"valuationTimestamp":{"type":"string","description":"Valuation timestamp (ISO8601)","example":"2025-01-15T14:30:00Z"},"priceExplain":{"type":"string","description":"Optional detailed pricing explanation"},"symbol":{"type":"string","description":"Currency pair symbol","example":"GBPUSD"}},"description":"Two-sided FX option valuation showing simultaneous bid/ask pricing"},"FXOptionTwoSidedValuationWithRiskStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/FXOptionTwoSidedValuationDTO"}},"description":"Two-sided valuation state containing bid/ask pricing with state metadata. When state is ERROR, the value field may still contain approximate pricing calculated from degraded market data."},"BatchUploadResponseDTO":{"type":"object","properties":{"processed":{"type":"integer","description":"Total number of records processed","format":"int32"},"inserted":{"type":"integer","description":"Number of records successfully inserted or updated","format":"int32"},"failed":{"type":"integer","description":"Number of records that failed to insert","format":"int32"},"errors":{"type":"array","description":"List of error messages for failed records","items":{"type":"string","description":"List of error messages for failed records"}}},"description":"Batch upload result with processing statistics"},"HistoricFXPriceSummary":{"type":"object","properties":{"source":{"type":"string"},"symbol":{"type":"string"},"firstStoredDate":{"type":"string"},"lastStoredDate":{"type":"string"},"totalRecordCount":{"type":"integer","format":"int32"},"fetchStartDate":{"type":"string"},"fetchEndDate":{"type":"string"},"updatedPriceCount":{"type":"integer","format":"int32"}}},"CurrencyPairDTOCreate":{"required":["baseCurrency","currencyPair","quoteCurrency"],"type":"object","properties":{"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"6-character code for the currency pair","example":"GBPUSD"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Base currency code","example":"GBP"},"quoteCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Quote currency code","example":"USD"},"isActive":{"type":"boolean","description":"Whether this currency pair is active for trading","example":true},"fwdRoute":{"type":"string","description":"How this pair's forward curve is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"DIRECT","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"volRoute":{"type":"string","description":"How this pair's volatility surface is obtained: DIRECT, or crossed from its two legs against USD or EUR.","example":"USD_CROSS","enum":["DIRECT","USD_CROSS","EUR_CROSS"]},"historicDataSource":{"type":"string","description":"External source that owns this pair's daily close price history.","example":"BOE","enum":["BOE","FRED","HKMA","UNKNOWN"]},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Additional calendar code for settlement holidays (e.g., USNY for cross-currency pairs)","example":"USNY"},"spotLagDays":{"maximum":2,"minimum":1,"type":"integer","description":"FX spot settlement lag in business days (T+N). 2 for most pairs; 1 for USD T+1 pairs such as USDCAD, USDTRY, USDPHP, USDRUB. Drives value/settlement date derivation.","format":"int32","example":2},"guardEnabled":{"type":"boolean","description":"Whether CurrencyGuard sells Guards on this pair. A commercial decision, separate from is_active (live rates wanted) and from whether the pair can be priced (a vol surface route with a spread multiplier). New pairs default to false so offering one is deliberate.","example":true}},"description":"Currency pair creation data"},"CurrencyDTOCreate":{"type":"object","properties":{"code":{"pattern":"^[A-Z]{3}$","type":"string","description":"ISO 4217 currency code","example":"GBP"},"description":{"maxLength":100,"minLength":10,"type":"string","description":"Description of the currency","example":"British Pound Sterling"},"precision":{"maximum":3,"minimum":0,"type":"integer","description":"Precision of the currency (number of decimal places)","format":"int32","example":2},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"isActive":{"type":"boolean","description":"Whether this currency is active. Tombstone flag: false = soft-deleted.","example":true},"rateRoute":{"type":"string","description":"How this currency's discount factors are obtained: DIRECT from a bought curve, or FX_IMPLIED from the USD curve and forward points.","example":"DIRECT","enum":["DIRECT","FX_IMPLIED"]}},"description":"Schema for representing a Currency"},"CounterpartyDTOCreate":{"required":["counterpartyType"],"type":"object","properties":{"counterpartyType":{"type":"string","description":"Type of counterparty: REGULATED_ENTITY, BROKER, PAYMENT_PROVIDER, BANK","example":"BROKER"},"name":{"maxLength":255,"minLength":1,"type":"string","description":"Name of the counterparty (e.g., a liquidity provider or bank)","example":"Example Bank"},"regulatedEntityId":{"type":"string","description":"Regulated entity ID (only for counterparty_type = REGULATED_ENTITY)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"}},"description":"Counterparty data to create"},"CgtEventSequenceRewind":{"type":"object","properties":{"previousSequence":{"type":"integer","description":"Sequence the processor was at before the rewind.","format":"int64","example":148213},"newSequence":{"type":"integer","description":"Sequence the processor was moved to.","format":"int64","example":148000},"message":{"type":"string","description":"Human-readable summary of what will be reprocessed."}},"description":"Result of rewinding the CGT trade event stream processor."},"CalendarDTOCreate":{"type":"object","properties":{"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"description":{"pattern":"^[A-Z]{4}$","type":"string","description":"Calendar description","example":"TARGET2/Eurozone  "},"isoCountryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 country code","example":"GB or TARGET2"},"isSundayWeekend":{"type":"boolean","description":"Indicates if Sunday is a weekend for this calendar","example":true},"isMondayWeekend":{"type":"boolean","description":"Indicates if Monday is a weekend for this calendar","example":false},"isTuesdayWeekend":{"type":"boolean","description":"Indicates if Tuesday is a weekend for this calendar","example":false},"isWednesdayWeekend":{"type":"boolean","description":"Indicates if Wednesday is a weekend for this calendar","example":false},"isThursdayWeekend":{"type":"boolean","description":"Indicates if Thursday is a weekend for this calendar","example":false},"isFridayWeekend":{"type":"boolean","description":"Indicates if Friday is a weekend for this calendar","example":false},"isSaturdayWeekend":{"type":"boolean","description":"Indicates if Saturday is a weekend for this calendar","example":true}},"description":"Schema for representing a Calendar"},"CalendarDateDTOCreate":{"type":"object","properties":{"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"Industry standard calendar codes","example":"EUTA"},"nonBusinessDate":{"type":"string","description":"Non business date for the calendar code","example":"2025-01-06"},"description":{"type":"string","description":"Non business date description","example":"Swiss National Day"}},"description":"Schema for representing a CalendarDate"},"AdminUserEntry":{"required":["email","firstName","lastName"],"type":"object","properties":{"email":{"type":"string","description":"Email address (must be @currencyguard.co.uk)","example":"admin@currencyguard.co.uk"},"firstName":{"type":"string","description":"First name","example":"Peter"},"lastName":{"type":"string","description":"Last name","example":"Atkinson"}},"description":"An admin user entry for bootstrapping"},"BootstrapAdminRequestDTO":{"required":["users"],"type":"object","properties":{"users":{"maxItems":10,"minItems":0,"type":"array","description":"Admin users to bootstrap","items":{"$ref":"#/components/schemas/AdminUserEntry"}}},"description":"Request to bootstrap admin users via invitation"},"BootstrapAdminResponseDTO":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the invitations were created successfully"},"message":{"type":"string","description":"Human-readable message"},"cognitoRegion":{"type":"string","description":"Cognito region for the provisioned pools"},"internalUserPoolId":{"type":"string","description":"Internal user pool ID for Cognito authentication"},"internalClientId":{"type":"string","description":"Internal user pool client ID for Cognito authentication"},"invitationTokens":{"type":"array","description":"Invitation tokens in the same order as the submitted emails","items":{"type":"string","description":"Invitation tokens in the same order as the submitted emails"}},"emailPreviews":{"type":"array","description":"Email previews in the same order as the submitted emails (non-production only)","items":{"$ref":"#/components/schemas/EmailPreviewDTO"}}},"description":"Response from bootstrap admin invitation creation"},"EmailPreviewDTO":{"type":"object","properties":{"from":{"type":"string","description":"Email sender address","example":"onboarding@currencyguard.co.uk"},"fromName":{"type":"string","description":"Email sender display name","example":"CurrencyGuard"},"to":{"type":"string","description":"Email recipient address","example":"user@example.com"},"subject":{"type":"string","description":"Email subject line","example":"Welcome to CurrencyGuard"},"htmlBody":{"type":"string","description":"HTML formatted email body","example":"<html><body><h1>Welcome!</h1><p>Click to login</p></body></html>"},"textBody":{"type":"string","description":"Plain text version of the email body","example":"Welcome to CurrencyGuard! Click the link to login: https://app.currencyguard.com/login"}},"description":"Email preview response with structured email content"},"AccountDTOCreate":{"type":"object","properties":{"accountCode":{"pattern":"^[0-9]{4}$","type":"string","description":"Account code (e.g., 1010, 4100) - Format: 1xxx=Assets, 2xxx=Liabilities, 3xxx=Equity, 4xxx=Revenue, 5xxx=Expenses","example":"1010"},"accountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"description":{"type":"string","description":"Description of the account","example":"Barclays bank account holding GBP cash"},"accountType":{"type":"string","description":"Account type: ASSET, LIABILITY, EQUITY, REVENUE, or EXPENSE","example":"ASSET"},"accountCategory":{"type":"string","description":"Account category (sub-classification)","example":"CASH"},"normalBalance":{"type":"string","description":"Normal balance side: DEBIT or CREDIT","example":"DEBIT"},"currency":{"pattern":"^[A-Z]{3}$","type":"string","description":"Currency code (GBP, EUR, USD) for fixed-currency accounts (balance sheet), or NULL for native-currency accounts (P&L). NULL means the account accepts postings in any currency.","example":"GBP"},"isActive":{"type":"boolean","description":"Whether this account is active","example":true},"counterpartyId":{"type":"string","description":"Optional counterparty associated with this account (broker, regulated entity, payment provider, etc.)","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"}},"description":"Schema for representing a Account"},"AccountPeriodDTOCreate":{"required":["periodName","periodStartDate"],"type":"object","properties":{"periodName":{"maxLength":50,"minLength":1,"type":"string","description":"Name of the account period","example":"Jan 2026"},"closeStepStatus":{"type":"string","description":"Current step in month-end close process","example":"STEP_2_FX_REVALUATION"},"closeStepProcessingMessage":{"type":"string","description":"Processing message or error from current close step","example":"Missing EOD rate for GBPUSD on 2025-12-31"},"periodStartDate":{"type":"string","description":"Start date of this accounting period (inclusive). Journal entries with value_date >= this date belong to this period.","example":"2026-01-01"},"periodEndDate":{"type":"string","description":"End date of this accounting period (inclusive). NULL means the period is open-ended. Journal entries with value_date <= this date belong to this period.","example":"2026-01-31"}},"description":"Schema for representing a AccountPeriod"},"WebhookSubscriptionUpdateRequestDTO":{"type":"object","properties":{"endpointUrl":{"maxLength":500,"minLength":0,"pattern":"^https://.+","type":"string","description":"New HTTPS endpoint URL","example":"https://psp.example.com/webhooks/currencyguard-v2"},"status":{"pattern":"^(ACTIVE|PAUSED|DISABLED)$","type":"string","description":"New status. ACTIVE resumes a paused subscription from its checkpoint; PAUSED or DISABLED stop delivery.","example":"ACTIVE","enum":["ACTIVE","PAUSED","DISABLED"]}},"description":"Request data for updating a webhook subscription"},"EventSubscriptionUpdateRequestDTO":{"type":"object","properties":{"status":{"pattern":"ACTIVE|PAUSED|DISABLED","type":"string","description":"New status for this subscription","nullable":true,"example":"PAUSED","enum":["ACTIVE","PAUSED","DISABLED"]}},"description":"Request data for updating an internal event subscription"},"ServerSentEventString":{"type":"object"},"HealthComponent":{"type":"object","properties":{"description":{"type":"string"},"status":{"type":"string"}}},"McpSpotRateDTO":{"type":"object","properties":{"currencyPair":{"type":"string"},"bid":{"type":"number"},"ask":{"type":"number"},"mid":{"type":"number"},"timestamp":{"type":"string","format":"date-time"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}}}},"McpGuardQuoteDTO":{"type":"object","properties":{"guardRate":{"type":"number"},"guardFee":{"type":"number"},"effectiveRate":{"type":"number"},"spotRate":{"type":"number"},"guardCurrency":{"type":"string"},"foreignCurrency":{"type":"string"},"payReceive":{"type":"string"},"foreignAmount":{"type":"number"},"guardAmount":{"type":"number"},"settlementDate":{"type":"string"},"settlementWindowFrom":{"type":"string"},"guardFeePct":{"type":"number"},"payLaterCreditFee":{"type":"number"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"stale":{"type":"boolean"}}},"McpForwardRateDTO":{"type":"object","properties":{"currencyPair":{"type":"string"},"tenor":{"type":"string"},"settlementDate":{"type":"string"},"spotMid":{"type":"number"},"forwardPoints":{"type":"number"},"forwardRate":{"type":"number"},"forwardBid":{"type":"number"},"forwardAsk":{"type":"number"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"timestamp":{"type":"string","format":"date-time"}}},"McpGuardExtensionQuoteDTO":{"type":"object","properties":{"extensionCost":{"type":"number"},"feeDifference":{"type":"number"},"guardSpreadCost":{"type":"number"},"extensionMargin":{"type":"number"},"originalGuardFee":{"type":"number"},"extendedGuardFee":{"type":"number"},"guardRate":{"type":"number"},"effectiveRate":{"type":"number"},"guardCurrency":{"type":"string"},"foreignCurrency":{"type":"string"},"payReceive":{"type":"string"},"foreignAmount":{"type":"number"},"guardAmount":{"type":"number"},"originalSettlementDate":{"type":"string"},"extendedSettlementDate":{"type":"string"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"timestamp":{"type":"string","format":"date-time"},"stale":{"type":"boolean"}}},"DocumentVersionDTO":{"type":"object","properties":{"versionId":{"type":"string","description":"Opaque version identifier","example":"a3e71ac1-d028-4ed9-932f-d04f956ebe17"},"latest":{"type":"boolean","description":"Whether this is the current revision","example":true},"size":{"type":"integer","description":"Size in bytes","format":"int64","example":84213},"lastModified":{"type":"string","description":"When this revision was written, ISO-8601","example":"2026-07-26T12:35:53Z"}},"description":"One retained revision of a document"},"UiConfigResponseDTO":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name","example":"dev"},"authMode":{"type":"string","description":"Authentication mode: 'direct' (MiniStack) or 'cognito' (AWS)"},"websocketDomain":{"type":"string","description":"WebSocket domain host:port","example":"dev-api.currencyguard.com"},"loginUrl":{"type":"string","description":"Frontend login page URL","example":"https://dev-app.currencyguard.com/login"},"logoUrl":{"type":"string","description":"Logo URL","example":"https://currencyguard.com/currencyguard-logo-social.png"},"totpIssuer":{"type":"string","description":"Issuer name shown in authenticator apps for TOTP codes","example":"CurrencyGuard-SANDBOX"}},"description":"Runtime UI configuration for frontend applications"},"PoolConfigDTO":{"type":"object","properties":{"displayName":{"type":"string"},"region":{"type":"string"},"userPoolId":{"type":"string"},"clientId":{"type":"string"},"hostedUiDomain":{"type":"string"},"totpIssuer":{"type":"string"}}},"PoolConfigResponseDTO":{"type":"object","properties":{"pools":{"type":"array","items":{"$ref":"#/components/schemas/PoolConfigDTO"}}}},"SalesUserDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this sales user (shared with cgo_user).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this sales user belongs to.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this sales user belongs to.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"isActive":{"type":"boolean","description":"Whether the sales user is currently active.","example":true},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a SalesUser"},"SalesUserFullProfileDTO":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/UserDTO"},"salesUser":{"$ref":"#/components/schemas/SalesUserDTO"},"regulatedEntity":{"$ref":"#/components/schemas/RegulatedEntityDTO"},"introducingBroker":{"$ref":"#/components/schemas/IntroducingBrokerDTO"}},"description":"Sales users belonging to this introducing broker, each with full user profile including PII"},"CustomerDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this customer (shared with cgo_user).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this customer belongs to.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this customer belongs to (denormalized from company).","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"companyId":{"type":"string","description":"The ID of the company this customer belongs to.","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"isActive":{"type":"boolean","description":"Whether the customer is currently active.","example":true},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a Customer"},"InternalUserDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this internal user (shared with cgo_user).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"currencyGuardCompanyId":{"type":"string","description":"The ID of the CurrencyGuard company this internal user works for.","format":"uuid","example":"00000000-0000-4000-8000-000000000000"},"isActive":{"type":"boolean","description":"Whether the internal user is currently active.","example":true},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a InternalUser"},"RegulatedUserDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this sales person (shared with cgo_user).","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this sales person works for.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"isActive":{"type":"boolean","description":"Whether the sales person is currently active.","example":true},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a RegulatedUser"},"UserFullProfileDTO":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/UserDTO"},"regulatedContext":{"$ref":"#/components/schemas/RegulatedUserDTO"},"salesUserContext":{"$ref":"#/components/schemas/SalesUserDTO"},"customerContext":{"$ref":"#/components/schemas/CustomerDTO"},"internalContext":{"$ref":"#/components/schemas/InternalUserDTO"}}},"TradingConfigurationDTO":{"type":"object","properties":{"name":{"type":"string","description":"Configuration key identifier","example":"currencyguard.trading.margin-rate"},"configType":{"type":"string","description":"Type of the configuration value","example":"BIGDECIMAL","enum":["BIGDECIMAL","STRING","INTEGER","BOOLEAN","JSON"]},"configDefault":{"type":"string","description":"Default value from application configuration","example":"0.007"},"description":{"type":"string","description":"Human-readable description of this configuration"},"allowedRoles":{"type":"string","description":"Comma-separated list of roles allowed to access this configuration","example":"REST_INTERNAL"},"globalOnly":{"type":"boolean","description":"True when the setting is a property of the platform rather than of a PSP relationship, and so can never be overridden for a single regulated entity","example":false},"value":{"type":"string","description":"The value in force for the requested scope","example":"0.0055"},"regulatedEntityId":{"type":"string","description":"Regulated entity this value was read from. Null when it is the platform-wide default.","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"source":{"type":"string","description":"Whether the value is this entity's own override or the inherited platform default","example":"GLOBAL","enum":["GLOBAL","OVERRIDE"]},"versionNumber":{"type":"integer","description":"Version number of the value row","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that last updated the value"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"A trading configuration setting resolved for a given scope"},"TenorDateMapping":{"type":"object","properties":{"tenor":{"type":"string","description":"The original tenor symbol or broken date from the request. Can be a standard tenor (TOD, ON, 1M, etc.) or an ISO date (YYYY-MM-DD)","example":"1M","enum":["TOD","ON","TN","SN","1D","2D","3D","1W","2W","1M","2M","3M","6M","9M","1Y","YYYY-MM-DD"]},"tenorDate":{"type":"string","description":"The resolved business date in ISO format (YYYY-MM-DD). Always a valid business day after adjustment. Null only if resolution failed.","example":"2025-02-03"},"isBusinessDay":{"type":"boolean","description":"Whether the originally requested tenor or date was already a business day (true) or required adjustment (false). Note: the returned tenorDate is always a business day.","example":true},"adjustmentReason":{"type":"string","description":"Reason for date adjustment when the calculated date fell on a non-business day","nullable":true,"example":"weekend_adjustment","enum":["weekend_adjustment","holiday_adjustment"]}},"description":"Mapping of a tenor symbol to its resolved business date with adjustment information"},"TenorResolutionResponseDTO":{"type":"object","properties":{"calendarSymbol":{"type":"string","description":"Calendar symbol used for resolution (GBPUSD for FX settlement, GBP for domestic, USNY for financial center)","example":"GBPUSD"},"referenceDate":{"type":"string","description":"Reference date used for tenor calculations in ISO format (YYYY-MM-DD)","example":"2025-01-02"},"resolutions":{"type":"array","description":"List of tenor to date mappings with adjustment information","items":{"$ref":"#/components/schemas/TenorDateMapping"}}},"description":"Tenor resolution response containing resolved business dates for requested tenors"},"EntityFundingAccountsDTO":{"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"The regulated entity these credentials belong to","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"railCode":{"type":"string","description":"The rail it settles through","example":"TRANSFERMATE"},"fundingAccounts":{"type":"array","description":"Payable accounts, one per account and currency","items":{"$ref":"#/components/schemas/FundingAccountDTO"}},"error":{"type":"string","description":"Why this rail could not be read, when it could not","example":"401 Unauthorized"}},"description":"One rail's funding accounts for one regulated entity"},"FundingAccountDTO":{"type":"object","properties":{"railAccountId":{"type":"string","description":"The rail's own account id — joins to the matching balance row","example":"743468"},"currencyCode":{"type":"string","description":"ISO 4217 currency this account funds in","example":"GBP"},"accountHolder":{"type":"string","description":"The legal holder of the account — the name a client pays TO","example":"CurrencyGuard Ltd"},"accountName":{"type":"string","description":"The provider's label for the account","example":"CGL Test GA GBP"},"accountNumber":{"type":"string","description":"Domestic account number, where the scheme uses one","example":"T000000863"},"iban":{"type":"string","description":"IBAN, where the scheme uses one; null where it does not","example":"GB87BKEN10000000000863T"},"sortCode":{"type":"string","description":"Sort code / routing / transit number, where the scheme uses one","example":"100000"},"bic":{"type":"string","description":"BIC / SWIFT, where the scheme uses one","example":"BKENGB33"}},"description":"One payable account in one currency — any coordinate is null where the scheme does not use it"},"FundingAccountsDTO":{"type":"object","properties":{"asOf":{"type":"string","description":"When these were read","example":"2026-10-01T09:14:02Z"},"entities":{"type":"array","description":"One group per regulated entity with a wallet-capable rail","items":{"$ref":"#/components/schemas/EntityFundingAccountsDTO"}}},"description":"Payable funding accounts at each configured payment rail — coordinates, not balances"},"SymbolResponse":{"type":"object","properties":{"symbol":{"type":"string"}}},"SourceResponse":{"type":"object","properties":{"source":{"type":"string"}}},"GuardSettlementPreviewDTO":{"type":"object","properties":{"guardId":{"type":"string","example":"GSP1000104"},"payReceive":{"type":"string","example":"PAY","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","example":10000},"foreignCurrency":{"type":"string","example":"USD"},"guardRate":{"type":"number","example":1.25},"guardAmount":{"type":"number","description":"The protected amount covering this slice — the cap the client can pay","example":8000},"guardCurrency":{"type":"string","example":"GBP"},"spotFxBid":{"type":"number","example":1.1995},"spotFxAsk":{"type":"number","example":1.2005},"settlementZone":{"type":"string","example":"PROTECTION","enum":["PROTECTION","SAVINGS","UNKNOWN"]},"fundingAmount":{"type":"number","description":"What the client sends: the cap (Pay) or the foreign amount (Receive)","example":8000},"fundingCurrency":{"type":"string","example":"GBP"},"conversionAmount":{"type":"number","description":"Indicative cost at the observed mid, for the savings route","example":7692.31},"fundingDeadline":{"type":"string","description":"When funds must arrive — the settlement window end","example":"2026-10-03T00:00:00Z"},"previewedAt":{"type":"string","example":"2026-10-01T09:30:00Z"},"settleable":{"type":"boolean","description":"False when a real settlement would be refused — see validationErrors","example":true},"validationErrors":{"type":"array","description":"Why a settlement would be refused, empty when settleable","items":{"type":"string","description":"Why a settlement would be refused, empty when settleable"}}},"description":"A read-only preview of settling a Guard: zone, route and funding, computed not written"},"GuardCancellationRefundDTO":{"type":"object","properties":{"guardId":{"type":"string","description":"ID of the guard","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"ageInMinutes":{"type":"integer","description":"Age of the guard in minutes since creation","format":"int64","example":1440},"daysUntilDueDate":{"type":"integer","description":"Number of days from now until the guard due date (settlement window end)","format":"int64","example":45},"maturityInDays":{"type":"integer","description":"Maturity period of the guard in days (from original creation to current due date)","format":"int64","example":60},"refundPercentage":{"type":"number","description":"Refund percentage applicable based on age and maturity (as decimal)","example":0.75},"guardFee":{"type":"number","description":"Original guard fee paid by the client","example":512},"maximumRefundAmount":{"type":"number","description":"Maximum refund amount available ((guardFee - originalSalesMargin) × refundPercentage)","example":384},"guardCurrency":{"type":"string","description":"Guard currency code","example":"GBP"},"cancellable":{"type":"boolean","description":"Whether this guard can be cancelled","example":true},"guardStatus":{"type":"string","description":"Current status of the guard","example":"ACTIVE"},"totalGuardFee":{"type":"number","description":"Total guard fee across all components in the extension chain","example":525.09},"refundCalculation":{"$ref":"#/components/schemas/GuardCancellationRefundDTORefundCalculation"},"validationErrors":{"type":"array","description":"Validation errors preventing cancellation (empty if cancellable)","items":{"type":"string","description":"Validation errors preventing cancellation (empty if cancellable)"}}},"description":"Guard cancellation refund calculation details"},"EntitlementDTO":{"type":"object","properties":{"key":{"type":"string","description":"The dot-notation key that corresponds to the JSON structure","example":"internal.risk-management.canEnterFXOptionTrades"},"description":{"type":"string","description":"Human-readable description of what this entitlement allows","example":"Entitles the internal user to enter FX option trades on behalf of customers"},"category":{"type":"string","description":"The category this entitlement belongs to","example":"internal.risk-management"},"scope":{"type":"string","description":"The scope of this entitlement (internal, sales, customer)","example":"internal"},"functionalArea":{"type":"string","description":"The functional area this entitlement covers","example":"risk-management"}},"description":"Represents an entitlement definition with metadata"},"EntitlementCategoryDTO":{"type":"object","properties":{"category":{"type":"string","description":"The category identifier","example":"internal.risk-management"},"scope":{"type":"string","description":"The scope of this category (internal, sales, customer)","example":"internal"},"functionalArea":{"type":"string","description":"The functional area this category covers","example":"risk-management"},"displayName":{"type":"string","description":"Display name for this category","example":"Internal Risk Management"},"entitlements":{"type":"array","description":"All entitlements within this category","items":{"$ref":"#/components/schemas/EntitlementDTO"}}},"description":"Represents a category of entitlements with grouped metadata"},"DocumentDTO":{"type":"object","properties":{"id":{"type":"string","description":"The document's stable identifier","format":"uuid","example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"},"documentType":{"type":"string","description":"The type of document being stored","example":"COMPANY_LOGO_FILE"},"entityId":{"type":"string","description":"The entity this document belongs to","format":"uuid","example":"660f9511-f3bc-52f6-c938-668877662111"},"contentType":{"type":"string","description":"MIME type of the stored file","example":"image/jpeg"},"fileSize":{"type":"integer","description":"Size of the file in bytes","format":"int64","example":84213},"updatedAt":{"type":"string","description":"When this revision was written, ISO-8601","example":"2026-07-26T12:35:53Z"},"piiData":{"$ref":"#/components/schemas/PiiData"}},"description":"A document belonging to an entity"},"PiiData":{"type":"object","properties":{"status":{"type":"string"},"value":{"$ref":"#/components/schemas/PiiDataValue"}},"description":"Document metadata (filename, tags). Encrypted at rest, decrypted at the edge.","example":{"original_filename":"logo.png","file_tags":["logo","image"]}},"CurrencyguardCompanyDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for CurrencyGuard company.","format":"uuid","example":"00000000-0000-4000-8000-000000000000"},"companyName":{"maxLength":200,"minLength":4,"type":"string","description":"The company name.","example":"CurrencyGuard Limited"},"registeredCompanyNumber":{"maxLength":20,"minLength":1,"type":"string","description":"The registered company number.","example":"12345678"},"contactEmail":{"maxLength":100,"minLength":0,"type":"string","description":"The main contact email address.","example":"info@currencyguard.co.uk"},"websiteUrl":{"maxLength":200,"minLength":0,"type":"string","description":"The company website URL.","example":"https://www.currencyguard.co.uk"},"phoneNumber":{"maxLength":20,"minLength":0,"pattern":"^\\+?[1-9]\\d{1,14}$","type":"string","description":"The primary contact phone number.","example":"+44 7768 298148"},"addressLine1":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 1.","example":"CurrencyGuard House"},"addressLine2":{"maxLength":100,"minLength":0,"type":"string","description":"The head office address line 2.","example":"123 Financial District"},"city":{"maxLength":50,"minLength":0,"type":"string","description":"The head office city.","example":"London"},"stateProvince":{"maxLength":50,"minLength":0,"type":"string","description":"The head office state/province.","example":"England"},"postcode":{"maxLength":15,"minLength":0,"type":"string","description":"The head office postcode.","example":"EC2A 4DP"},"countryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"The head office country code.","example":"GB"},"companyLogoDocumentId":{"type":"string","description":"The company logo document.","format":"uuid","example":"12345678-1234-4001-8000-123456789012"},"calendarCode":{"pattern":"^[A-Z]{4}$","type":"string","description":"The calendar code for this company's trading operations.","example":"GBLO"},"calendarTimezone":{"maxLength":50,"minLength":0,"type":"string","description":"The timezone for this company's trading operations.","example":"Europe/London"},"operatingHours":{"$ref":"#/components/schemas/CurrencyguardCompanyDTOOperatingHours"},"isActive":{"type":"boolean","description":"Whether CurrencyGuard company record is active.","example":true},"oauthPoolId":{"type":"string","description":"The OAuth pool CurrencyGuard staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000004"},"systemOauthPoolId":{"type":"string","description":"The OAuth pool system accounts authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000005"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"system"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a CurrencyguardCompany"},"CompanyWithCustomersDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this company.","format":"uuid","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"regulatedEntityId":{"type":"string","description":"The ID of the regulated entity this company belongs to.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"introducingBrokerId":{"type":"string","description":"The ID of the introducing broker this company belongs to.","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"status":{"type":"string","description":"The status of this company.","example":"ENABLED","enum":["PENDING","ENABLED","DISABLED","DELETED"]},"piiData":{"$ref":"#/components/schemas/CompanyWithCustomersDTOPiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this company's users authenticate against, shared with its broker.","format":"uuid","example":"0a111111-0000-4000-8000-000000000003"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"baseCurrency":{"pattern":"^[A-Z]{3}$","type":"string","description":"The company's functional/home currency (ISO 4217). Defaults the guard currency for this company's guards.","example":"GBP"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"},"customers":{"type":"array","description":"List of customers associated with this company","example":[{"id":"12345678-1234-4001-8000-123456789012","piiData":{"email":"john@example.com"}}],"items":{"$ref":"#/components/schemas/UserDTO"}}},"description":"Schema for representing a Company with its associated customers"},"BestWorstFxPerformancePeriodDTO":{"type":"object","properties":{"performanceType":{"type":"string","description":"The type of performance result, either 'BEST' or 'WORST'","example":"BEST"},"performancePercentage":{"type":"number","description":"The calculated performance as a percentage (positive = appreciation, negative = depreciation)","example":5.25},"startDate":{"type":"string","description":"The start date of the performance window in ISO8601 date format","example":"2008-09-15"},"endDate":{"type":"string","description":"The end date of the performance window in ISO8601 date format","example":"2009-03-15"},"windowSizeInDays":{"type":"integer","description":"The size of the analysis window in days","format":"int32","example":180},"periodInYears":{"type":"integer","description":"The overall lookback period analyzed, in years (e.g., 5, 10, or 25 years)","format":"int32","example":25},"startRate":{"type":"number","description":"The FX rate at the start of the performance window","example":1.3842},"endRate":{"type":"number","description":"The FX rate at the end of the performance window","example":1.2156},"startAmount":{"type":"number","description":"The base currency cost at the start of the performance window (foreignAmount / startRate)","example":36120},"finalAmount":{"type":"number","description":"The base currency cost at the end of the performance window (foreignAmount / endRate)","example":41132},"deltaAmount":{"type":"number","description":"The change in base currency cost over the window (finalAmount - startAmount)","example":5012}},"description":"A best or worst performing period in historical FX rate data"},"BestWorstHistoricFxPerformanceResponseDTO":{"type":"object","properties":{"payReceive":{"type":"string","description":"Indicates whether this is a PAY or RECEIVE scenario","example":"RECEIVE","enum":["PAY","RECEIVE"]},"foreignAmount":{"type":"number","description":"The foreign currency amount being analyzed","example":50000},"guardAmount":{"type":"number","description":"The guard amount in the base currency used as the delta baseline","example":36232},"quoteCurrency":{"type":"string","description":"The quote currency (foreign currency in the pair)","example":"USD"},"baseCurrency":{"type":"string","description":"The base currency (domestic currency in the pair)","example":"GBP"},"today":{"type":"string","description":"The reference date for the analysis (ISO8601 date format)","example":"2025-01-02"},"periodInDaysRemaining":{"type":"integer","description":"The duration of the target period in days (from today to settlement date)","format":"int64","example":180},"performances":{"type":"array","description":"List of best and worst performing periods found in the historical data. Each entry represents either a BEST or WORST period for a specific lookback window (e.g., 5, 10, 25 years).","items":{"$ref":"#/components/schemas/BestWorstFxPerformancePeriodDTO"}},"explanation":{"type":"string","description":"Client-friendly explanation of the best/worst historic performance analysis"}},"description":"Response containing best/worst historical FX performance analysis results"},"HedgeCoverageByCurrencyPairDTO":{"type":"object","properties":{"currencyPair":{"type":"string","description":"Currency pair (guard currency + foreign currency)","example":"GBPUSD"},"guardCurrencyCode":{"type":"string","description":"Guard (base) currency ISO code","example":"GBP"},"foreignCurrencyCode":{"type":"string","description":"Foreign (quote) currency ISO code — the currency of all sums below","example":"USD"},"priced":{"type":"boolean","description":"False when no valid spot was available for the pair (sums are then zero, ratios null)"},"intrinsicValueProtectionZone":{"type":"number","description":"(1) Sum of guard intrinsic value in the protection zone"},"intrinsicValueSettlementWindow":{"type":"number","description":"(2) Sum of guard intrinsic value in the protection zone AND settlement window"},"optionMtmProtectionZone":{"type":"number","description":"(3) Sum of back-to-back option mid MtM for the (1) guards"},"optionMtmSettlementWindow":{"type":"number","description":"(4) Sum of back-to-back option mid MtM for the (2) guards"},"hedgeIntrinsicValueProtectionZone":{"type":"number","description":"(5) Sum of back-to-back option intrinsic value (no time value) for the (1) guards"},"hedgeIntrinsicValueSettlementWindow":{"type":"number","description":"(6) Sum of back-to-back option intrinsic value (no time value) for the (2) guards"},"overallCoverageRatio":{"type":"number","description":"Overall coverage ratio (3)/(1); null when (1) is zero","example":0.98},"settlementWindowCoverageRatio":{"type":"number","description":"Settlement-window coverage ratio (4)/(2); null when (2) is zero","example":1.01},"guardCountProtectionZone":{"type":"integer","description":"Number of guards in the protection zone","format":"int32"},"guardCountSettlementWindow":{"type":"integer","description":"Number of guards in the protection zone AND settlement window","format":"int32"},"guardCountTotal":{"type":"integer","description":"Total in-scope guards for this pair","format":"int32"},"orphanOptionMtm":{"type":"number","description":"(7) Sum of mid MtM of the pair's orphan options (options with no linked guard), foreign currency"},"orphanOptionIntrinsicValue":{"type":"number","description":"(8) Sum of intrinsic value (no time value) of the pair's orphan options, foreign currency"},"orphanOptionCount":{"type":"integer","description":"Number of orphan options for this pair","format":"int32"},"overallCoverageRatioInclOrphan":{"type":"number","description":"Coverage ratio including the orphan buffer ((3)+(7))/(1); null when (1) is zero","example":1.03}},"description":"Hedge coverage figures for a single currency pair"},"HedgeCoverageReportDTO":{"type":"object","properties":{"asOf":{"type":"string","description":"Valuation instant the figures were computed at (ISO-8601 UTC)","example":"2026-06-24T14:19:39Z"},"currencyPairs":{"type":"array","description":"Per-currency-pair coverage figures","items":{"$ref":"#/components/schemas/HedgeCoverageByCurrencyPairDTO"}}},"description":"Per-currency-pair hedge coverage report for the regulated entity"},"IntroducingBrokerWithSalesUsersAndCompaniesDTO":{"type":"object","properties":{"introducingBroker":{"$ref":"#/components/schemas/IntroducingBrokerDTO"},"salesUsers":{"type":"array","description":"Sales users belonging to this introducing broker","items":{"$ref":"#/components/schemas/SalesUserDTO"}},"companies":{"type":"array","description":"Companies belonging to this introducing broker","items":{"$ref":"#/components/schemas/CompanyDTO"}}},"description":"An introducing broker together with its associated sales users and companies"},"IntroducingBrokerWithFullDetailsDTO":{"type":"object","properties":{"introducingBroker":{"$ref":"#/components/schemas/IntroducingBrokerDTO"},"salesUsers":{"type":"array","description":"Sales users belonging to this introducing broker, each with full user profile including PII","items":{"$ref":"#/components/schemas/SalesUserFullProfileDTO"}},"companies":{"type":"array","description":"Companies belonging to this introducing broker, each with customers and documents","items":{"$ref":"#/components/schemas/CompanyWithCustomersDTO"}}},"description":"An introducing broker together with its sales users (including PII), companies, customers, and documents"},"ApiClientDTO":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"clientName":{"type":"string"},"description":{"type":"string"},"cognitoClientId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"enabled":{"type":"boolean"}}},"JobSummaryDTO":{"type":"object","properties":{"jobName":{"type":"string"},"jobGroup":{"type":"string"},"description":{"type":"string"},"state":{"type":"string"},"nextFireTime":{"type":"string"},"previousFireTime":{"type":"string"},"cronExpression":{"type":"string"},"supportsCutBackfill":{"type":"boolean"}}},"JobDetailDTO":{"type":"object","properties":{"jobName":{"type":"string"},"jobGroup":{"type":"string"},"description":{"type":"string"},"jobClassName":{"type":"string"},"durable":{"type":"boolean"},"triggers":{"type":"array","items":{"$ref":"#/components/schemas/TriggerInfoDTO"}}}},"TriggerInfoDTO":{"type":"object","properties":{"triggerName":{"type":"string"},"triggerGroup":{"type":"string"},"description":{"type":"string"},"cronExpression":{"type":"string"},"timeZone":{"type":"string"},"nextFireTime":{"type":"string"},"previousFireTime":{"type":"string"},"triggerState":{"type":"string"}}},"JobExecutionDTO":{"type":"object","properties":{"jobName":{"type":"string"},"jobGroup":{"type":"string"},"fireTime":{"type":"string"},"runTime":{"type":"integer","format":"int64"},"success":{"type":"boolean"},"status":{"type":"string"},"errorMessage":{"type":"string"},"resultMessage":{"type":"string"}}},"ClusterStatusDTO":{"type":"object","properties":{"schedulerName":{"type":"string"},"instanceId":{"type":"string"},"clustered":{"type":"boolean"},"started":{"type":"boolean"},"standby":{"type":"boolean"},"shutdown":{"type":"boolean"},"numberOfJobsExecuted":{"type":"integer","format":"int32"},"runningSince":{"type":"string"}}},"FieldInfo":{"type":"object","properties":{"category":{"type":"string","enum":["VALUE","DATE","CURRENCY","ENUM","STRING"]},"enumValues":{"type":"array","items":{"type":"string"}}}},"TradingReferenceMappingDTO":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"TradingReferenceMappingsDTO":{"type":"object","properties":{"counterparties":{"type":"array","items":{"$ref":"#/components/schemas/TradingReferenceMappingDTO"}}}},"EventProcessorStatus":{"type":"object","properties":{"currentEventSequence":{"type":"integer","description":"Sequence number the processor has reached.","format":"int64","example":148213},"status":{"type":"string","description":"Processor state.","example":"running"}},"description":"Current position and state of an event stream processor."},"ProcessingTypeDTO":{"type":"object","properties":{"value":{"type":"string","description":"Processing type value used in the database","example":"JournalEntryProcessing"},"description":{"type":"string","description":"Human-readable description of what this processing type does","example":"Creates journal entries (ledger postings) for financial transactions"}},"description":"Processing type definition for trade event rules"},"EventTypeDTO":{"type":"object","properties":{"value":{"type":"string","description":"Event type value used in the database and event stream","example":"Guard"},"description":{"type":"string","description":"Human-readable description of what events of this type represent","example":"Guard trade events including status transitions and fee calculations"}},"description":"Event type definition for trade event processing rules"},"HospitalCountDTO":{"type":"object","properties":{"count":{"type":"integer","format":"int64"}}},"PerimeterStorageDTO":{"type":"object","properties":{"documentCount":{"type":"integer","description":"Documents belonging to entities in this perimeter","format":"int64","example":412},"totalBytes":{"type":"integer","description":"Their combined size in bytes","format":"int64","example":18874368}},"description":"Documents held in a perimeter's store, counted live"},"TenantPerimeterMembershipDTO":{"type":"object","properties":{"perimeterId":{"type":"string","description":"The perimeter these members belong to","format":"uuid","example":"cccccccc-0000-4000-8000-000000000001"},"total":{"type":"integer","description":"Total rows inside the perimeter","format":"int32","example":180},"roots":{"type":"array","description":"Entities whose parent is not also in this perimeter. Normally exactly one — more than one means an unrelated entity shares the perimeter, or a perimeter_id has drifted from its parent's","items":{"$ref":"#/components/schemas/TenantPerimeterNodeDTO"}}},"description":"Everything inside a tenant perimeter, arranged as the tenant hierarchy arranges it"},"TenantPerimeterNodeDTO":{"type":"object","properties":{"type":{"type":"string","description":"Which level of the tenant hierarchy this is","example":"INTRODUCING_BROKER","enum":["CURRENCYGUARD_COMPANY","REGULATED_ENTITY","INTRODUCING_BROKER","COMPANY"]},"id":{"type":"string","description":"The entity's ID","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"perimeterId":{"type":"string","description":"The perimeter this entity is actually in. Where it differs from the perimeter being queried, this entity has been segregated into its own — it still appears here, in its real place in the hierarchy, and everything beneath it belongs to that other perimeter too. The ARNs are not repeated per node: look the perimeter up in GET /tenant-perimeters, which returns them all.","format":"uuid","example":"cccccccc-0000-4000-8000-000000000001"},"userIds":{"type":"array","description":"Users owned by this entity that are also in this perimeter","items":{"type":"string","description":"Users owned by this entity that are also in this perimeter","format":"uuid"}},"invitationIds":{"type":"array","description":"Invitations addressed to this entity that are also in this perimeter","items":{"type":"string","description":"Invitations addressed to this entity that are also in this perimeter","format":"uuid"}},"children":{"type":"array","description":"Entities one level down sharing this perimeter. Empty for a leaf, or where a child has been segregated away","items":{"$ref":"#/components/schemas/TenantPerimeterNodeDTO"}}},"description":"One entity inside a perimeter, with the users, invitations and child entities hanging off it"},"KeyStateDTO":{"type":"object","properties":{"keyArn":{"type":"string","description":"The key asked about","example":"arn:aws:kms:eu-west-2:123456789012:key/abc-123"},"state":{"type":"string","description":"AWS key state, verbatim","example":"PendingDeletion","enum":["Enabled","Disabled","PendingDeletion","PendingImport","Unavailable","UNKNOWN"]},"deletionDate":{"type":"string","description":"When the key will be destroyed, or null if no destruction is scheduled. A key already in PendingDeletion refuses every operation NOW — this is the deadline for cancelling, not when the data becomes unreadable.","example":"2026-08-31T00:00:00Z"},"createdAt":{"type":"string","description":"When AWS created the key. Also the age of this perimeter's encryption: Rotate Key provisions a new key rather than versioning this one.","example":"2026-06-01T09:14:22Z"},"validTo":{"type":"string","description":"When imported key material expires. Null for AWS-generated keys, which is every key this platform creates — a KMS key otherwise has no expiry.","example":"null"},"rotationEnabled":{"type":"boolean","description":"Whether AWS rotates the backing material automatically. Distinct from this platform's Rotate Key, which moves the data onto a different key entirely. Null when AWS would not answer.","example":false},"usable":{"type":"boolean","description":"Whether the key can currently encrypt and decrypt. False while pending deletion.","example":false},"reachable":{"type":"boolean","description":"False when KMS could not be asked at all — no key, no credentials, key gone. The other fields say nothing in that case, and 'unknown' must not be shown as 'fine'.","example":true}},"description":"Live KMS state of a perimeter's key"},"AuthUrlResponseDTO":{"type":"object","properties":{"authUrl":{"type":"string"}}},"AuthStatusResponseDTO":{"type":"object","properties":{"isAuthenticated":{"type":"boolean"},"isConnected":{"type":"boolean"},"authUrl":{"type":"string"},"message":{"type":"string"}}},"RegulatedEntityWithRegulatedUsersDTO":{"type":"object","properties":{"id":{"type":"string","description":"The ID for this regulated entity.","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"entityReferenceCode":{"pattern":"^[A-Z0-9]{2}$","type":"string","description":"Two-character code identifying this regulated entity in customer-facing references, e.g. the 'SP' in Guard reference GSP1000104. Immutable once a Guard has been issued under it.","example":"SP"},"piiData":{"$ref":"#/components/schemas/RegulatedEntityWithRegulatedUsersDTOPiiData"},"oauthPoolId":{"type":"string","description":"The OAuth pool this regulated entity's staff authenticate against.","format":"uuid","example":"0a111111-0000-4000-8000-000000000001"},"perimeterId":{"type":"string","description":"The tenant perimeter whose KMS key encrypts this record's PII.","format":"uuid","example":"cccccccc-cc11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"Event sequence number for event sourcing.","format":"int64","example":12345},"versionNumber":{"type":"integer","description":"The strictly monotonically increasing version number for this record.","format":"int32","example":1},"updatedBy":{"type":"string","description":"The username of the person or entity that updated this record.","example":"jbloggs24"},"updatedAt":{"type":"string","description":"The timestamp of the last update in UTC.","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"The timestamp of creation in UTC.","example":"2024-10-18T12:30:40Z"},"regulatedUsers":{"type":"array","description":"List of regulated users associated with this regulated entity","example":[{"id":"12345678-1234-4001-8000-123456789012","piiData":{"email":"sales@example.com"}}],"items":{"$ref":"#/components/schemas/UserDTO"}}},"description":"Schema for representing a Regulated Entity with its associated regulated users"},"AggregatedRiskBucketDTO":{"type":"object","properties":{"snapshot":{"type":"boolean"},"key":{"type":"string","description":"Message routing key: {currencyPair}:{bucketId}","example":"GBPUSD:1d-1w"},"currency_pair":{"type":"string","description":"Currency pair code","example":"GBPUSD"},"bucket_id":{"type":"string","description":"Bucket identifier","example":"1d-1w"},"exposure":{"$ref":"#/components/schemas/BucketedRiskExposureDTO"},"is_snapshot":{"type":"boolean","description":"True if this is part of initial snapshot, false if incremental update"}},"description":"Aggregated risk for a single maturity bucket"},"AggregatedRiskBucketStateDTO":{"required":["emissionTimestamp","valid","valueTimestamp"],"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the price data is currently valid (true) or in an error/degraded state (false). When false, the value may still be present (stale/approximate data).","example":true},"errorMessages":{"type":"array","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":["Market data feed delayed by 30 seconds","Volatility surface is stale"],"items":{"type":"string","description":"List of error messages explaining why the state is invalid. Empty/null when valid=true. Can contain multiple accumulated errors from different sources.","example":"[\"Market data feed delayed by 30 seconds\",\"Volatility surface is stale\"]"}},"valueTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when the underlying data was produced at the source (business time). This represents the data's original timestamp.","example":"2024-03-01T14:30:15.123Z"},"emissionTimestamp":{"type":"string","description":"ISO 8601 timestamp indicating when our system emitted this state (system/processing time). This represents when the wrapper was created.","example":"2024-03-01T14:30:16.456Z"},"subscriptionSource":{"type":"string","description":"Market data subscription channel identifier. Used for debugging and monitoring data flows.","example":"DEFAULT"},"emissionSource":{"type":"string","description":"Identifier of the market data provider or internal pricing engine that produced this data. Diagnostic detail for internal use only — omitted from responses to non-internal callers."},"infoMessages":{"type":"array","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers.","items":{"type":"string","description":"Informational messages providing context about the price state (e.g., validation details, reference source checks). Do not affect validity. Diagnostic detail for internal use only — omitted from responses to non-internal callers."}},"value":{"$ref":"#/components/schemas/AggregatedRiskBucketDTO"}},"description":"Container for aggregated risk bucket data with state information. The 'value' field contains risk metrics and can be present even when valid=false (stale/approximate data)."},"BucketedRiskExposureDTO":{"type":"object","properties":{"bucket":{"$ref":"#/components/schemas/RiskBucketDTO"},"guard_mark_to_market":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"option_mark_to_market":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"guard_mark_to_market_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"option_mark_to_market_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_delta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_gamma":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_vega":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_theta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_delta_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_gamma_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_vega_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"net_theta_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"realised_pnl":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"cash_delta":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"cash_delta_mid":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"cash_realised_pnl":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"cash_unrealised_pnl":{"$ref":"#/components/schemas/CurrencyAmountDTO"},"cash_count":{"type":"integer","description":"Number of cash FX positions in this bucket","format":"int32","example":3},"guard_count":{"type":"integer","description":"Number of guard positions in this bucket","format":"int32","example":5},"option_count":{"type":"integer","description":"Number of hedge option positions in this bucket","format":"int32","example":2},"error_count":{"type":"integer","description":"Number of positions with stale or errored prices in this bucket","format":"int32","example":0},"total_position_count":{"type":"integer","description":"Total number of positions in this bucket","format":"int32","example":7}},"description":"Risk exposure for a single maturity bucket"},"RiskBucketDTO":{"type":"object","properties":{"id":{"type":"string","description":"Bucket identifier","example":"1d-1w"},"min_days":{"type":"integer","description":"Minimum days to expiry (inclusive)","format":"int32","example":1},"max_days":{"type":"integer","description":"Maximum days to expiry (exclusive), null for unbounded","format":"int32","example":7},"sort_order":{"type":"integer","description":"Display order for this bucket","format":"int32","example":1},"label":{"type":"string","description":"Human-readable label for this bucket","example":"1 day - 1 week"}},"description":"Maturity bucket definition for risk aggregation"},"EntityWalletsDTO":{"type":"object","properties":{"regulatedEntityId":{"type":"string","description":"The regulated entity these credentials belong to","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"railCode":{"type":"string","description":"The rail it settles through","example":"TRANSFERMATE"},"balances":{"type":"array","description":"Balances, one per account and currency","items":{"$ref":"#/components/schemas/WalletBalanceDTO"}},"error":{"type":"string","description":"Why this rail could not be read, when it could not","example":"401 Unauthorized"}},"description":"One rail's balances for one regulated entity"},"WalletBalancesDTO":{"type":"object","properties":{"asOf":{"type":"string","description":"When these were read","example":"2026-09-25T09:14:02Z"},"entities":{"type":"array","description":"One group per regulated entity with a wallet-capable rail","items":{"$ref":"#/components/schemas/EntityWalletsDTO"}}},"description":"Balances held at each configured payment rail"},"PaymentAllocationDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this allocation","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"paymentId":{"type":"string","description":"The payment being applied; null for a write-off","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"obligationId":{"type":"string","description":"The debt being settled","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"allocatedAmount":{"type":"number","description":"How much of the payment applies to this debt","example":5000},"regulatedEntityId":{"type":"string","description":"PSP whose business this allocation is; null means CurrencyGuard's own book","format":"uuid","example":"aaaaaaaa-aa11-4001-8000-000000000000"},"eventSequence":{"type":"integer","description":"This row's position in the payment event stream","format":"int64","example":8105},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"system"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"},"allocationKind":{"type":"string","description":"CASH for money a payment moved, WRITE_OFF for debt given up","example":"CASH"},"writeOffReason":{"type":"string","description":"Why the debt was written off; required for a WRITE_OFF"}},"description":"Schema for representing a PaymentAllocation"},"RailBeneficiariesDTO":{"type":"object","properties":{"asOf":{"type":"string","description":"When these were read","format":"date-time","example":"2026-09-25T09:14:02Z"},"rails":{"type":"array","description":"One group per rail instance with a beneficiary-capable adapter","items":{"$ref":"#/components/schemas/RailInstanceBeneficiariesDTO"}}},"description":"Every configured rail's own beneficiary list, read live"},"RailBeneficiaryDTO":{"type":"object","properties":{"state":{"type":"string","description":"MAPPED, NOT_PAYABLE, MAPPING_BROKEN or UNMAPPED_RAIL_PAYEE — see the capability model's §2 for what each means and why a fifth state, an unmapped party of ours, is not produced here yet","example":"MAPPED"},"mappingId":{"type":"string","description":"Our mapping's own id, when a mapping exists (absent for UNMAPPED_RAIL_PAYEE)","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"payeeCompanyId":{"type":"string","description":"The company this is mapped to, when a mapping exists and the payee is one","example":"6ba7b810-9dad-11d1-80b4-00c04fd430c8"},"payeeRegulatedEntityId":{"type":"string","description":"The regulated entity this is mapped to, when a mapping exists and the payee is one","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"payeeSelfRail":{"type":"string","description":"The destination rail code, when a mapping exists and the payee is ourselves at another rail","example":"WISE_PLATFORM_API"},"mappingCurrency":{"type":"string","description":"The currency the MAPPING itself is scoped to — may differ from the live payee's currency if either side has drifted, and null means the mapping serves any currency","example":"GBP"},"railBeneficiaryId":{"type":"string","description":"The rail's own identifier for this payee. Present even when MAPPING_BROKEN — it is our pointer's value, not confirmation the rail still has it.","example":"TM-BEN-448210"},"name":{"type":"string","description":"The payee's name on the rail","example":"Northwind Payroll Ltd"},"currency":{"type":"string","description":"ISO 4217 currency this payee is scoped to, null if the rail does not scope by currency","example":"GBP"},"accountIdentifier":{"type":"string","description":"The rail's account identifier for this payee, in full — an account number or an IBAN carries no access on its own, so it is not truncated or masked here","example":"IE36IRCE99990100048707"},"payable":{"type":"boolean","description":"Whether an instruction naming this payee would be accepted right now. Null for MAPPING_BROKEN — the rail has nothing to ask, so there is no answer, not a false one","example":true},"payableReason":{"type":"string","description":"Why not, when it is not","example":"Pending verification"},"rawAttributes":{"type":"object","additionalProperties":{"type":"object","description":"The rail's raw record for this payee, exactly as received — for diagnosis only, not a stable contract"},"description":"The rail's raw record for this payee, exactly as received — for diagnosis only, not a stable contract"}},"description":"One coverage row: a payee, or a mapping, or both, depending on state"},"RailInstanceBeneficiariesDTO":{"type":"object","properties":{"railInstanceId":{"type":"string","description":"The rail instance this address book belongs to","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"regulatedEntityId":{"type":"string","description":"The regulated entity these credentials belong to","example":"c7516512-5416-4edd-b856-3a3ae6163c59"},"railCode":{"type":"string","description":"The rail it settles through","example":"TRANSFERMATE_PAYMENTS_API"},"beneficiaries":{"type":"array","description":"Coverage rows: every payee the rail reports, joined against our own mappings","items":{"$ref":"#/components/schemas/RailBeneficiaryDTO"}},"error":{"type":"string","description":"Why this rail could not be read, when it could not","example":"401 Unauthorized"}},"description":"One rail instance's beneficiaries"},"AwaitingApprovalDTO":{"type":"object","properties":{"payment":{"$ref":"#/components/schemas/PaymentDTO"},"obligationSourceEntityId":{"type":"string","description":"The debt's lineage — Guard, option or manual","example":"GSP1000104-E01"},"obligationSource":{"type":"string","description":"What raised the debt","example":"GUARD_DELIVERY"},"obligationReason":{"type":"string","description":"Why a manual debt was raised; null otherwise"},"gbpEquivalent":{"type":"number","description":"GBP equivalent at the current mid; null if no rate","example":11360},"waitingBecause":{"type":"string","description":"Why it was not auto-approved","example":"Over the GBP 10000 auto-approve limit"}},"description":"A payment awaiting approval, with its debt, GBP equivalent and why a person is needed"},"OnboardingReferenceMappingDTO":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"OnboardingReferenceMappingsDTO":{"type":"object","properties":{"regulatedEntities":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingReferenceMappingDTO"}},"introducingBrokers":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingReferenceMappingDTO"}},"companies":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingReferenceMappingDTO"}},"users":{"type":"array","items":{"$ref":"#/components/schemas/UserReferenceMappingDTO"}}}},"UserReferenceMappingDTO":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"},"identifier":{"type":"string"},"userType":{"type":"string"}}},"OauthClientRefDTO":{"type":"object","properties":{"app":{"type":"string","description":"Which application this client serves","example":"WHITE_LABEL","enum":["WHITE_LABEL","DEV_PORTAL","RISK_APP","EVENT_STREAM","SENTINEL"]},"clientId":{"type":"string","description":"Cognito app client ID","example":"1a2b3c4d5e6f7g8h9i0j"}},"description":"An app client registered on a pool"},"OauthPoolMembershipDTO":{"type":"object","properties":{"roots":{"type":"array","description":"Roots of the tenant hierarchy — normally the single CurrencyGuard company","items":{"$ref":"#/components/schemas/OauthPoolNodeDTO"}}},"description":"Every entity and the Cognito pools it authenticates against"},"OauthPoolNodeDTO":{"type":"object","properties":{"type":{"type":"string","description":"Which level of the tenant hierarchy this is","example":"INTRODUCING_BROKER","enum":["CURRENCYGUARD_COMPANY","REGULATED_ENTITY","INTRODUCING_BROKER","COMPANY"]},"id":{"type":"string","description":"The entity","format":"uuid","example":"eeeeeeee-ee55-4001-8000-000000000000"},"name":{"type":"string","description":"The entity's name, where it is not PII. Set for CurrencyGuard only; resolve the others from the entity endpoints.","example":"CURRENCYGUARD LTD"},"pools":{"type":"array","description":"Pools this entity authenticates against. Two for a broker, one for most.","items":{"$ref":"#/components/schemas/OauthPoolViewDTO"}},"children":{"type":"array","description":"Entities one level down","items":{"$ref":"#/components/schemas/OauthPoolNodeDTO"}}},"description":"An entity, the OAuth pools it authenticates against, and its children"},"OauthPoolViewDTO":{"type":"object","properties":{"poolId":{"type":"string","description":"The pool row","format":"uuid","example":"0a111111-0000-4000-8000-000000000001"},"principalType":{"type":"string","description":"The kind of principal that authenticates against the pool","example":"CUSTOMER","enum":["INTERNAL","SYSTEM","REGULATED","SALES","CUSTOMER"]},"displayName":{"type":"string","description":"Name shown in the pool picker","example":"ScioPay"},"region":{"type":"string","description":"AWS region","example":"eu-west-1"},"userPoolId":{"type":"string","description":"Cognito user pool ID","example":"eu-west-1_AbCdEfGhI"},"hostedUiDomain":{"type":"string","description":"Cognito Hosted UI domain","example":"https://dev-customer-auth.currencyguard.com"},"authSubdomain":{"type":"string","description":"Route this pool's login page is served on, under our own domain.","example":"baumann-partners-sales"},"totpIssuer":{"type":"string","description":"Name shown in this pool's users' authenticator apps beside their TOTP code.","example":"CurrencyGuard-SANDBOX"},"cognitoGroup":{"type":"string","description":"Group new users of this pool join","example":"REST_CUSTOMER"},"clients":{"type":"array","description":"App clients registered on this pool","items":{"$ref":"#/components/schemas/OauthClientRefDTO"}},"emailDomains":{"type":"array","description":"Email domains that route to this pool","items":{"type":"string","description":"Email domains that route to this pool"}},"perimeterId":{"type":"string","description":"Perimeter whose KMS key encrypts this pool's PII","format":"uuid","example":"cccccccc-0000-4000-8000-000000000001"}},"description":"A Cognito pool as used by one entity"},"HostedLoginPageDTO":{"type":"object","properties":{"userPoolId":{"type":"string","description":"The Cognito user pool","example":"eu-west-1_AbCdEfGhI"},"clientId":{"type":"string","description":"The app client the link signs in as","example":"1a2b3c4d5e6f7g8h9i0j"},"app":{"type":"string","description":"Which application that client was registered for","example":"WHITE_LABEL","enum":["WHITE_LABEL","DEV_PORTAL","RISK_APP","EVENT_STREAM","SENTINEL"]},"hostedUiDomain":{"type":"string","description":"The pool's Hosted UI domain","example":"https://dev-customer-auth.currencyguard.com"},"loginUrl":{"type":"string","description":"The full authorize URL to open","example":"https://dev-customer-auth.currencyguard.com/login?response_type=code&client_id=..."}},"description":"A pool's branded Hosted UI login page"},"VolInterpolationResultDTO":{"type":"object","properties":{"currencyPair":{"type":"string"},"valuationDatetime":{"type":"string"},"strike":{"type":"number"},"expiryDate":{"type":"string"},"bidVol":{"type":"number"},"askVol":{"type":"number"},"midVol":{"type":"number"},"spotBid":{"type":"number"},"spotAsk":{"type":"number"},"spotMid":{"type":"number"},"bidVolExplain":{"type":"string"},"askVolExplain":{"type":"string"},"midVolExplain":{"type":"string"}}},"CutoffInfoDTO":{"type":"object","properties":{"cutoff":{"type":"string","description":"Market data cutoff time","example":"0900LON"},"valuationDate":{"type":"string","description":"Valuation date for this cutoff","example":"2026-01-28T00:00:00Z"},"updatedAt":{"type":"string","description":"Last update timestamp","example":"2026-01-28T09:15:00Z"},"valuationDatetime":{"type":"string","description":"Full valuation datetime (spot quotes only)","example":"2026-01-28T09:00:00Z"},"type":{"type":"string","description":"Quote type discriminator","example":"FXSpot"},"quote":{"$ref":"#/components/schemas/CutoffInfoDTOQuote"},"source":{"type":"string","description":"Source that published this snapshot","example":"ICE"}},"description":"Market data cutoff metadata"},"PriceSourceTree":{"type":"object","properties":{"sources":{"type":"array","description":"Every registered price source, with its configuration and current state.","items":{"$ref":"#/components/schemas/PriceSourceTreeSource"}},"tree":{"type":"array","description":"The source tree in configuration form: one entry per source, naming the source it delegates to where there is one.","items":{"$ref":"#/components/schemas/PriceSourceTreeNode"}},"root":{"type":"string","description":"Name of the source at the root of the tree.","example":"MANUAL"},"operationalInfo":{"$ref":"#/components/schemas/PriceSourceTreeOperationalInfo"}},"description":"Configuration and operational state of a market-data price source tree."},"PriceSourceTreeNode":{"type":"object","properties":{"name":{"type":"string","description":"Name of this source.","example":"MANUAL"},"delegateSource":{"type":"string","description":"Name of the source this one delegates to, when it is a delegating source. Absent for a leaf.","example":"ICE_SPOT"}},"description":"The source tree in configuration form: one entry per source, naming the source it delegates to where there is one."},"PriceSourceTreeOperationalInfo":{"type":"object","properties":{"totalSources":{"type":"integer","description":"Number of registered sources.","format":"int32","example":4},"timestamp":{"type":"string","description":"When this snapshot was taken, ISO 8601.","example":"2026-09-02T10:15:30Z"}},"description":"Summary of the tree as a whole."},"PriceSourceTreeSource":{"type":"object","properties":{"name":{"type":"string","description":"Unique name of the source.","example":"MANUAL"},"className":{"type":"string","description":"Fully qualified class implementing the source."},"type":{"type":"string","description":"Source type, where one is registered.","example":"PRIMARY"},"description":{"type":"string","description":"Human-readable description, where one is registered."},"properties":{"$ref":"#/components/schemas/PriceSourceTreeSourceProperties"},"operationalState":{"$ref":"#/components/schemas/PriceSourceTreeSourceOperationalState"}},"description":"Every registered price source, with its configuration and current state."},"SettlementConversionPreviewDTO":{"type":"object","properties":{"settlementId":{"type":"string","description":"The settlement, which is also the conversion's reference on the rail"},"railInstanceId":{"type":"string","description":"The rail instance the conversion runs on"},"railAdapter":{"type":"string","description":"The rail's adapter","example":"SIMULATED"},"sellCurrency":{"type":"string","description":"Currency to sell","example":"USD"},"buyCurrency":{"type":"string","description":"Currency to buy","example":"GBP"},"fixedSide":{"type":"string","description":"Which side is fixed (rule 11): BUY — a Pay buys exactly the invoice; SELL — a Receive sells exactly what the client sent","enum":["BUY","SELL"]},"sellAmount":{"type":"number","description":"Amount to sell (quoted when the buy side is fixed)","example":135423},"buyAmount":{"type":"number","description":"Amount to buy (quoted when the sell side is fixed)","example":100000},"quotedRate":{"type":"number","description":"The rate the zone is decided at: the rail's quote, or the struck rate when a conversion already exists — on the traded pair's convention","example":1.35423},"railQuoteId":{"type":"string","description":"The rail's quote id, to pass to convert-and-execute; absent when the rail issues none"},"quoteExpiresAt":{"type":"string","description":"When the quote expires (ISO-8601); refresh the preview after this"},"quoteBinding":{"type":"boolean","description":"Whether the rail will honour the quoted price, or merely re-price near it"},"observedMid":{"type":"number","description":"CGL's mid now, which the shortfall and true-up are measured against","example":1.3522},"settlementZone":{"type":"string","description":"The zone at the quoted rate","enum":["PROTECTION","SAVINGS"]},"guardAmount":{"type":"number","description":"The cap (Pay) or floor (Receive) for this settlement, in guard currency"},"clientConversionAmount":{"type":"number","description":"What the client's own all-in costs (Pay) or yields (Receive) at CGL's mid, guard currency"},"shortfallAmount":{"type":"number","description":"The shortfall on the observed-mid basis, as execution records it in shortfall_amount — zero in SAVINGS. For a funded settlement the cash CGL actually adds is cglTopUpAmount"},"shortfallCurrency":{"type":"string","description":"Currency of the shortfall: foreign on a Pay, guard on a Receive"},"savingsRebateAmount":{"type":"number","description":"What CGL returns to a Guard-Pay client in SAVINGS, guard currency"},"expectedTrueUpAmount":{"type":"number","description":"The true-up execution would book at this rate, guard currency (indicative)"},"expectedReFxMarginAmount":{"type":"number","description":"The RE's FX margin on this conversion against CGL's mid, guard currency (indicative)"},"cglTopUpAmount":{"type":"number","description":"CGL top-up from its own wallet, guard currency: Pay max(0, sold − cap); Receive max(0, floor − bought). What CGL funds on a funded settlement (spec 06 §2, §4)"},"fundingSurplusAmount":{"type":"number","description":"Left in CGL's wallet from the client's funding, guard currency: Pay max(0, cap − sold)"},"existingConversion":{"$ref":"#/components/schemas/SettlementConversionDTO"}},"description":"Preview of converting and executing a funded settlement on the regulated entity's rail"},"GuardDrillDownDTO":{"type":"object","properties":{"guard":{"$ref":"#/components/schemas/GuardDTOInternal"},"guardHedgeFXOption":{"$ref":"#/components/schemas/FXOptionTradeDTO"},"guardSettlements":{"type":"array","items":{"$ref":"#/components/schemas/GuardSettlementWithHedgeDTO"}}}},"GuardSettlementWithHedgeDTO":{"type":"object","properties":{"guardSettlementDTOInternal":{"$ref":"#/components/schemas/GuardSettlementDTOInternal"},"settlementHedgeFXOption":{"$ref":"#/components/schemas/FXOptionTradeDTO"}}},"MarginRateResponse":{"type":"object","properties":{"marginRate":{"type":"number","description":"Margin rate as decimal (e.g., 0.007 = 0.7%)","example":0.007}}},"FXSwapQuoteDTO":{"type":"object","properties":{"nearLeg":{"$ref":"#/components/schemas/FXTradeQuoteDTO"},"farLeg":{"$ref":"#/components/schemas/FXTradeQuoteDTO"},"bidSwapPoints":{"type":"number","description":"Bid swap points (sell near / buy far): farBid - nearAsk","example":0.00087},"askSwapPoints":{"type":"number","description":"Ask swap points (buy near / sell far): farAsk - nearBid","example":0.0009},"swapPoints":{"type":"number","description":"Mid swap points (average of bid and ask swap points)","example":0.000885},"timestamp":{"type":"string","description":"Quote generation timestamp in ISO-8601 format","example":"2025-01-09T10:30:15.123Z"},"expiryTime":{"type":"string","description":"Quote expiry time (optional)","example":"2025-01-09T10:30:45.123Z"},"quoteId":{"type":"string","description":"Quote ID for tracking (optional)","example":"q-swap-12345-67890"}},"description":"Executable price quote for an FX swap trade (NEAR + FAR legs)"},"FXTradeQuoteDTO":{"type":"object","properties":{"currencyPair":{"type":"string","description":"Currency pair in 6-character format (e.g., GBPUSD)","example":"GBPUSD"},"tradeType":{"type":"string","description":"Trade type","example":"SPOT","enum":["SPOT","FORWARD"]},"amount":{"type":"number","description":"Amount in base currency","example":100000},"valueDate":{"type":"string","description":"Settlement date in ISO-8601 format","example":"2025-01-15T00:00:00Z"},"bidRate":{"type":"number","description":"BID rate (customer can SELL base currency at this rate)","example":1.2645},"askRate":{"type":"number","description":"ASK rate (customer can BUY base currency at this rate)","example":1.2647},"bidForwardPoints":{"type":"number","description":"BID forward points (null for SPOT trades)","example":0.0012},"askForwardPoints":{"type":"number","description":"ASK forward points (null for SPOT trades)","example":0.00126},"bidSettlementAmount":{"type":"number","description":"Settlement amount if customer sells (amount × bidRate)","example":126450},"askSettlementAmount":{"type":"number","description":"Settlement amount if customer buys (amount × askRate)","example":126470},"spotBidRate":{"type":"number","description":"Spot bid rate used as basis (for reference)","example":1.2633},"spotAskRate":{"type":"number","description":"Spot ask rate used as basis (for reference)","example":1.26344},"timestamp":{"type":"string","description":"Quote generation timestamp in ISO-8601 format","example":"2025-01-09T10:30:15.123Z"},"expiryTime":{"type":"string","description":"Quote expiry time (optional)","example":"2025-01-09T10:30:45.123Z"},"quoteId":{"type":"string","description":"Quote ID for tracking (optional)","example":"q-12345-67890"}},"description":"Two-way price quote for an FX trade (bid/ask)"},"FXPositionPnLDTO":{"type":"object","properties":{"id":{"type":"string","description":"ID for this position P&L entry","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"currencyPair":{"pattern":"^[A-Z]{6}$","type":"string","description":"Currency pair for this position","example":"GBPUSD"},"valueDate":{"type":"string","description":"Settlement value date for this position bucket","example":"2025-12-23"},"sourceEntityId":{"type":"string","description":"ID of the source entity that generated this P&L lot (e.g. FXTrade ID, Guard ID)","example":"CCG0000001"},"regulatedEntityId":{"type":"string","description":"ID of the regulated entity associated with this position","format":"uuid","example":"9e107d9d-372d-4add-ae2d-f3d1d41fd1d7"},"counterpartyId":{"type":"string","description":"ID of the counterparty the originating trade was executed with","format":"uuid","example":"11111111-1111-1111-1111-111111111111"},"fxTradeEventSequence":{"type":"integer","description":"Event sequence of the originating trade - ties back to the trade event stream","format":"int64","example":12345},"eventSequence":{"type":"integer","description":"Own event sequence number from the global trade event sequence - used for event sourcing this entity","format":"int64","example":12346},"tradeTimestamp":{"type":"string","description":"Execution timestamp of the trade - determines FIFO ordering within a value date","example":"2025-12-21T09:30:00Z"},"buySell":{"pattern":"^(BUY|SELL)$","type":"string","description":"Direction of this lot","example":"BUY","enum":["BUY","SELL"]},"originalAmount":{"type":"number","description":"Original trade amount in the base currency","example":100000},"price":{"type":"number","description":"Trade execution price","example":1.25},"remainingAmount":{"type":"number","description":"Remaining open amount after FIFO matching - decreases as this lot is closed against","example":60000},"position":{"type":"number","description":"Running net position in base currency after this lot is processed - positive for long, negative for short","example":60000},"averageCost":{"type":"number","description":"Running weighted average cost of the open position after this lot is processed","example":1.2531},"incrementalRealisedPnl":{"type":"number","description":"Incremental realised P&L for this specific lot in quote currency - the P&L caused by this trade event. Positive for gains, negative for losses. Zero for position-increasing trades.","example":250},"versionNumber":{"type":"integer","description":"Strictly monotonically increasing version number for this record","format":"int32","example":1},"updatedBy":{"type":"string","description":"Username of the person or entity that updated this record","example":"TradeEventProcessor"},"updatedAt":{"type":"string","description":"Timestamp of the last update in UTC","example":"2024-10-18T12:30:40Z"},"createdAt":{"type":"string","description":"Timestamp of creation in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a FXPositionPnL"},"EventDTO":{"type":"object","properties":{"eventSequence":{"type":"integer","description":"Monotonically increasing event sequence number","format":"int64","example":12345},"eventType":{"type":"string","description":"The type of event","example":"Guard"},"updatedAt":{"type":"string","description":"Timestamp when the record was last updated with milliseconds","format":"date-time","example":"2025-01-02T11:00:00.123Z"},"oldState":{"$ref":"#/components/schemas/EventDTOOldState"},"newState":{"$ref":"#/components/schemas/EventDTONewState"}},"description":"Event sourcing DTO containing event sequence, type, timestamp, old state, and new state"},"CgtEventProcessorStatus":{"type":"object","properties":{"currentEventSequence":{"type":"integer","description":"Sequence number the processor has reached.","format":"int64","example":148213},"status":{"type":"string","description":"Processor state.","example":"running"}},"description":"Current position and state of the CGT trade event stream processor."},"GridPoint":{"type":"object","properties":{"shiftValue":{"type":"number","description":"The shift value for this grid point"},"valuation":{"$ref":"#/components/schemas/ValuationDTO"}},"description":"A single grid point (one shift value) for this position"},"SensitivityGridResultDTO":{"type":"object","properties":{"gridType":{"type":"string","description":"Perturbation axis (D_SPOT or D_VOL)"},"stepSize":{"type":"number","description":"Step size used for the grid"},"rangeMin":{"type":"number","description":"Minimum shift value"},"rangeMax":{"type":"number","description":"Maximum shift value"},"positionId":{"type":"string","description":"Position UUID","example":"123e4567-e89b-12d3-a456-426614174000"},"symbol":{"type":"string","description":"Currency pair symbol","example":"GBPUSD"},"book":{"type":"string","description":"Book","example":"GUARD_BOOK"},"direction":{"type":"string","description":"Position direction","example":"BUY"},"notional":{"type":"number","description":"Notional in base currency"},"sourceType":{"type":"string","description":"Position source type","example":"GUARD"},"expiryDate":{"type":"string","description":"Option expiry date in ISO8601 format","example":"2025-12-31T00:00:00Z"},"gridPoints":{"type":"array","description":"Grid points in order from rangeMin to rangeMax","items":{"$ref":"#/components/schemas/GridPoint"}}},"description":"Sensitivity grid result for a single position across all shift points"},"ValidationResult":{"type":"object","properties":{"isValid":{"type":"boolean"},"message":{"type":"string"}}},"AccountPeriodBalanceDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this period balance record","format":"uuid"},"accountPeriodId":{"type":"string","description":"Account period ID","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"accountPeriodPeriodName":{"maxLength":50,"minLength":1,"type":"string","description":"Name of the account period","example":"Jan 2026"},"accountCode":{"type":"string","description":"Account code","example":"1010"},"accountCodeAccountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"currency":{"type":"string","description":"Currency code","example":"GBP"},"dateBasis":{"type":"string","description":"Date basis: TRADE, VALUE, or ACTUAL","example":"TRADE"},"openingBalance":{"type":"number","description":"Opening balance at start of period (carried from previous period)","example":5000},"periodDebitTotal":{"type":"number","description":"Total debits during this period","example":10000},"periodCreditTotal":{"type":"number","description":"Total credits during this period","example":7500},"closingBalance":{"type":"number","description":"Closing balance at end of period (opening + debits - credits)","example":7500},"computedAt":{"type":"string","description":"Timestamp when this balance was computed","example":"2025-12-31T23:59:59Z"},"updatedAt":{"type":"string","description":"Timestamp of last update","example":"2025-12-31T23:59:59Z"}},"description":"Schema for representing a AccountPeriodBalance"},"AccountBalanceDTO":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this account balance record","format":"uuid"},"accountPeriodId":{"type":"string","description":"Account period ID","format":"uuid","example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"accountPeriodPeriodName":{"maxLength":50,"minLength":1,"type":"string","description":"Name of the account period","example":"Jan 2026"},"accountCode":{"type":"string","description":"Account code","example":"1010"},"accountCodeAccountName":{"maxLength":255,"minLength":1,"type":"string","description":"Account name","example":"Barclays GBP Nostro"},"currency":{"type":"string","description":"Currency code","example":"GBP"},"balanceDate":{"type":"string","description":"Balance date","example":"2025-12-05"},"dateBasis":{"type":"string","description":"Date basis: TRADE, VALUE, or ACTUAL","example":"TRADE"},"debitTotal":{"type":"number","description":"Total debits for this account/currency/date","example":1000},"creditTotal":{"type":"number","description":"Total credits for this account/currency/date","example":500},"closingBalance":{"type":"number","description":"Running balance as of end of this date (cumulative from start of ledger)","example":500},"updatedAt":{"type":"string","description":"Timestamp of last update in UTC","example":"2024-10-18T12:30:40Z"}},"description":"Schema for representing a AccountBalance"},"DeletionSummaryDTO":{"type":"object","properties":{"paymentAllocationsDeleted":{"type":"integer","description":"Number of payment allocations deleted (including history)","format":"int64","example":23},"paymentsDeleted":{"type":"integer","description":"Number of payments deleted (including history)","format":"int64","example":30},"paymentObligationsDeleted":{"type":"integer","description":"Number of payment obligations deleted (including history)","format":"int64","example":56},"journalEntriesDeleted":{"type":"integer","description":"Number of journal entries deleted","format":"int64","example":1523},"accountBalancesDeleted":{"type":"integer","description":"Number of account balances deleted (daily and monthly)","format":"int64","example":245},"hospitalRecordsDeleted":{"type":"integer","description":"Number of ledger trade-event hospital records deleted (including history)","format":"int64","example":4},"fxTradesDeleted":{"type":"integer","description":"Number of FX cash trades and legs deleted (including history)","format":"int64","example":12},"guardSettlementsDeleted":{"type":"integer","description":"Number of guard settlements deleted","format":"int64","example":89},"fxOptionTradesDeleted":{"type":"integer","description":"Number of FX option trades deleted","format":"int64","example":156},"guardsDeleted":{"type":"integer","description":"Number of guards deleted","format":"int64","example":78},"guardQuotesDeleted":{"type":"integer","description":"Number of guard quotes deleted","format":"int64","example":134},"fxPositionPnlDeleted":{"type":"integer","description":"Number of FX position P&L records deleted (including history)","format":"int64","example":40},"totalDeleted":{"type":"integer","description":"Total number of records deleted across all tables","format":"int64","example":2225},"deletedBy":{"type":"string","description":"Username of the user who performed the deletion","example":"admin@currencyguard.com"}},"description":"Summary of deleted trading data records"},"EntitlementsDTO":{"type":"object","properties":{"internal":{"type":"object","properties":{"ledger":{"type":"object","properties":{"canModifyScheduler":{"type":"boolean","description":"Entitles the internal user to schedule, pause, resume, and trigger scheduled jobs in the ledger domain"},"canModifyChartOfAccounts":{"type":"boolean","description":"Entitles the internal user to create, update, and deactivate chart of accounts entries"},"canModifyAccountPeriods":{"type":"boolean","description":"Entitles the internal user to create, update, and manage account periods and month-end close workflows"},"canEnterJournals":{"type":"boolean","description":"Entitles the internal user to create, batch-create, and reverse journal entry pairs"}},"additionalProperties":true,"description":"Ledger permissions"},"market-data":{"type":"object","properties":{"canModifySpotFX":{"type":"boolean","description":"Entitles the internal user to configure spot FX price sources, set manual prices, and manage spot quote data"},"canModifyForwardCurves":{"type":"boolean","description":"Entitles the internal user to configure forward curve price sources and manage forward curve quote data"},"canModifyIRCurves":{"type":"boolean","description":"Entitles the internal user to configure interest rate curve price sources and manage IR curve quote data"},"canModifyVolSurfaces":{"type":"boolean","description":"Entitles the internal user to configure vol surface price sources and manage vol surface quote data"},"canModifyHistoricFXPrices":{"type":"boolean","description":"Entitles the internal user to sync, upload, and delete historic FX price data"},"canAuthenticateSaxo":{"type":"boolean","description":"Entitles the internal user to manage Saxo authentication sessions (login, logout, refresh)"}},"additionalProperties":true,"description":"Market data permissions"},"sales-users":{"type":"object","properties":{"canDisableSalesUser":{"type":"boolean","description":"Entitles the internal user to disable (suspend) sales users"},"canEnableSalesUser":{"type":"boolean","description":"Entitles the internal user to re-enable a disabled sales user"},"canDeleteSalesUserPii":{"type":"boolean","description":"Entitles the internal user to permanently delete a sales user's PII data"}},"additionalProperties":true,"description":"Sales users permissions"},"templates":{"type":"object","properties":{"canEditEntitlementTemplate":{"type":"boolean","description":"Entitles the internal user to create, update, and manage entitlements templates"},"canEditEmailTemplate":{"type":"boolean","description":"Entitles the internal user to create, update, and manage invitation email templates"}},"additionalProperties":true,"description":"Templates permissions"},"payments":{"type":"object","properties":{"canRaisePayments":{"type":"boolean","description":"Entitles the internal user to raise payments and allocate them against debts — the MAKER half of maker-checker"},"canApprovePayments":{"type":"boolean","description":"Entitles the internal user to APPROVE a payment. Deliberately separate from raising one: granting both to the same person defeats maker-checker at the entitlement level, before the checker <> maker rule ever gets a chance to bite"},"canRaiseManualObligations":{"type":"boolean","description":"Entitles the internal user to raise a debt by hand against a counterparty — one no trade event raises, booked to the ledger on creation"},"canWriteOffObligations":{"type":"boolean","description":"Entitles the internal user to write off part or all of a debt owed to CurrencyGuard, or to reverse an earlier write-off. Separate from raising payments: giving up money owed is a decision, not cash application"},"canReprocessObligations":{"type":"boolean","description":"Entitles the internal user to reprocess one Guard's payment obligations — re-run the current rules and reconcile against what exists. Read-only preview; it never rewrites a debt money has moved against"}},"additionalProperties":true,"description":"Payments permissions"},"my-profile":{"type":"object","properties":{"canModifyMyAvatar":{"type":"boolean","description":"Entitles the internal user to upload and delete their own avatar"},"canModifyMyUserDetails":{"type":"boolean","description":"Entitles the internal user to update their own profile details"},"canEditOwnEntitlement":{"type":"boolean","description":"Entitles the internal user to modify their own entitlements"}},"additionalProperties":true,"description":"My profile permissions"},"api-clients":{"type":"object","properties":{"canManageApiClients":{"type":"boolean","description":"Entitles the internal user to create, view, rotate, and delete system-level API clients"},"canManageWebhooks":{"type":"boolean","description":"Entitles the internal user to register, renew, suspend, and delete webhook subscriptions against the internal trade and onboarding event streams. The internal counterpart of regulated.api-clients.canManageWebhooks. Also held by the system account, which registers and renews the cross-domain sync subscriptions on startup"},"canReplayWebhooks":{"type":"boolean","description":"Entitles the internal user to restate a webhook subscription's cursor and replay historic events. Separated from canManageWebhooks because replay re-delivers events that have already been consumed, which double-processes on any non-idempotent consumer"}},"additionalProperties":true,"description":"Api clients permissions"},"users":{"type":"object","properties":{"canModifyUser":{"type":"boolean","description":"Entitles the internal user to create, update, and manage user accounts"},"canDisableInternalUser":{"type":"boolean","description":"Entitles the internal user to disable (suspend) other internal users"},"canEnableInternalUser":{"type":"boolean","description":"Entitles the internal user to re-enable a disabled internal user"},"canDeleteInternalUserPii":{"type":"boolean","description":"Entitles the internal user to permanently delete an internal user's PII data"},"canDisableRegulatedUser":{"type":"boolean","description":"Entitles the internal user to disable (suspend) regulated users"},"canEnableRegulatedUser":{"type":"boolean","description":"Entitles the internal user to re-enable a disabled regulated user"},"canDeleteRegulatedUserPii":{"type":"boolean","description":"Entitles the internal user to permanently delete a regulated user's PII data"},"canInviteInternalUser":{"type":"boolean","description":"Entitles the internal user to invite and onboard other internal CurrencyGuard users"},"canInviteRegulatedUser":{"type":"boolean","description":"Entitles the internal user to invite and onboard regulated users"},"canResetUserMfa":{"type":"boolean","description":"Entitles the internal user to reset MFA (TOTP) for any user, forcing re-enrollment on next login"}},"additionalProperties":true,"description":"Users permissions"},"system":{"type":"object","properties":{"canModifyTradingConfigs":{"type":"boolean","description":"Entitles the internal user to modify trading domain configuration settings"},"canModifyOnboardingConfig":{"type":"boolean","description":"Entitles the internal user to update onboarding configuration settings"},"canModifyTenantPerimeters":{"type":"boolean","description":"Entitles the internal user to ringfence and merge tenants, replace a perimeter's encryption key, and set ringfencing policy. Every one of these re-encrypts a tenant's data and provisions or retires AWS resources, but none destroys anything"},"canShredTenantPerimeterKey":{"type":"boolean","description":"Entitles the internal user to destroy a perimeter's encryption key, making every row, document and backup belonging to that tenant permanently unreadable, and to cancel a destruction within its window. This is the tenant-wide counterpart of the canDelete*Pii entitlements: those erase one person's data from the tables that hold it, whereas this erases everyone in the perimeter at once and reaches copies no delete statement can — backups, replicas, exports. Held apart from the other perimeter operations because it is the only one with no way back"},"canImportTrades":{"type":"boolean","description":"Entitles the internal user to bulk-import trades from a JSON export, writing directly into the trade book and bypassing the normal booking and pricing path. The counterpart of canDeleteAllTrades, with the same blast radius in the opposite direction"},"canAcceptEventDeliveries":{"type":"boolean","description":"Entitles the caller to submit batches of domain events into a consuming domain. Held by the system account rather than by people: it is what lets the trading and ledger hexagons receive pushed trade, trade-reference, and onboarding events. Revoking it halts cross-domain sync"},"canModifyScheduler":{"type":"boolean","description":"Entitles the internal user to schedule, pause, resume, and trigger scheduled jobs in the trading domain"},"canModifySystemClock":{"type":"boolean","description":"Entitles the internal user to start, stop, rewind, and otherwise manipulate the system clock"},"canModifyTradeEventProcessingRules":{"type":"boolean","description":"Entitles the internal user to create, update, and delete trade event processing rules and rule versions"},"canModifyObligationRules":{"type":"boolean","description":"Entitles the internal user to create, update, and deactivate settlement obligation rules — which decide what debt a trade event raises, and for how much"},"canResubmitTradeEventProcessing":{"type":"boolean","description":"Entitles the internal user to rewind event sequences, discharge and retry failed trade event processing"},"canDeleteAllTrades":{"type":"boolean","description":"Entitles the internal user to permanently delete all trading data (destructive, dev/test only)"},"canModifyMfaSettings":{"type":"boolean","description":"Entitles the internal user to enable or disable MFA (TOTP) on Cognito user pools"}},"additionalProperties":true,"description":"System permissions"},"risk-management":{"type":"object","properties":{"canEnterFxOptionTrade":{"type":"boolean","description":"Entitles the internal user to enter FX option trades on behalf of customers"},"canPriceOptions":{"type":"boolean","description":"Entitles the internal user to reprice options and run what-if option valuation scenarios"},"canEnterFxCashTrade":{"type":"boolean","description":"Entitles the internal user to enter FX cash trades on behalf of customers"},"canBuyGuard":{"type":"boolean","description":"Entitles the internal user to enter guard trades on behalf of customers"},"canSettleGuard":{"type":"boolean","description":"Entitles the internal user to settle existing guard positions"},"canExtendGuard":{"type":"boolean","description":"Entitles the internal user to extend guard position expiration dates"},"canVoidGuard":{"type":"boolean","description":"Entitles the internal user to void a guard whose fee was never received, unwinding its hedge"}},"additionalProperties":true,"description":"Risk management permissions"},"reference-data":{"type":"object","properties":{"canModifyCurrency":{"type":"boolean","description":"Entitles the internal user to create, update, and manage currency configurations"},"canModifyCalendar":{"type":"boolean","description":"Entitles the internal user to create, update, and manage trading calendars"},"canModifyCurrencyPair":{"type":"boolean","description":"Entitles the internal user to create and update tradeable currency pairs"},"canModifyTradingHours":{"type":"boolean","description":"Entitles the internal user to set the trading enabled and outside-hours trading flags"},"canModifyGuardMarginSchedule":{"type":"boolean","description":"Entitles the internal user to create and update guard margin schedules"},"canModifyCounterparties":{"type":"boolean","description":"Entitles the internal user to create and update counterparty records"}},"additionalProperties":true,"description":"Reference data permissions"},"invitations":{"type":"object","properties":{"canViewAllInvitation":{"type":"boolean","description":"Entitles the internal user to view all invitations across the entire system"},"canManageAllInvitation":{"type":"boolean","description":"Entitles the internal user to manage and modify all invitations across the entire system"}},"additionalProperties":true,"description":"Invitations permissions"},"parties":{"type":"object","properties":{"canModifyIntroducingBroker":{"type":"boolean","description":"Entitles the internal user to create and update introducing broker records"},"canModifyRegulatedEntity":{"type":"boolean","description":"Entitles the internal user to create, update, and manage regulated entities"},"canModifyRegulatedEntityLogo":{"type":"boolean","description":"Entitles the internal user to upload and delete logos for regulated entities"},"canModifyCompany":{"type":"boolean","description":"Entitles the internal user to create, update, and manage company information"},"canModifyCurrencyGuardCompany":{"type":"boolean","description":"Entitles the internal user to update CurrencyGuard company configuration"}},"additionalProperties":true,"description":"Parties permissions"},"customers":{"type":"object","properties":{"canDisableCustomer":{"type":"boolean","description":"Entitles the internal user to disable (suspend) customer users"},"canEnableCustomer":{"type":"boolean","description":"Entitles the internal user to re-enable a disabled customer user"},"canDeleteCustomerPii":{"type":"boolean","description":"Entitles the internal user to permanently delete a customer user's PII data"}},"additionalProperties":true,"description":"Customers permissions"}},"additionalProperties":true,"description":"Permissions for internal users"},"regulated":{"type":"object","properties":{"companies":{"type":"object","properties":{"canDisableCompany":{"type":"boolean","description":"Entitles the regulated user to disable (suspend) a company within their regulated entity"},"canEnableCompany":{"type":"boolean","description":"Entitles the regulated user to re-enable a disabled company within their regulated entity"},"canDeleteCompanyPii":{"type":"boolean","description":"Entitles the regulated user to permanently delete a company's PII data within their regulated entity"}},"additionalProperties":true,"description":"Companies permissions"},"system":{"type":"object","properties":{"canModifyMfaSettings":{"type":"boolean","description":"Entitles the regulated user to enable or disable MFA (TOTP) on their regulated entity's Cognito user pool"}},"additionalProperties":true,"description":"System permissions"},"risk-management":{"type":"object","properties":{"canBuyGuard":{"type":"boolean","description":"Entitles the regulated user to enter guard trades for their customers"},"canSettleGuard":{"type":"boolean","description":"Entitles the regulated user to settle existing guard positions for their customers"},"canExtendGuard":{"type":"boolean","description":"Entitles the regulated user to extend guard position expiration dates for their customers"}},"additionalProperties":true,"description":"Risk management permissions"},"invitations":{"type":"object","properties":{"canViewInvitation":{"type":"boolean","description":"Entitles the regulated user to view invitations within their scope of responsibility"},"canManageInvitation":{"type":"boolean","description":"Entitles the regulated user to manage and modify invitations within their scope of responsibility"}},"additionalProperties":true,"description":"Invitations permissions"},"sales-users":{"type":"object","properties":{"canModifySalesUser":{"type":"boolean","description":"Regulated user can create/update sales users (CRM-style, no invitation)"},"canDisableSalesUser":{"type":"boolean","description":"Entitles the regulated user to disable (suspend) sales users within their regulated entity"},"canEnableSalesUser":{"type":"boolean","description":"Entitles the regulated user to re-enable a disabled sales user within their regulated entity"},"canDeleteSalesUserPii":{"type":"boolean","description":"Entitles the regulated user to permanently delete a sales user's PII data within their regulated entity"},"canInviteSalesUser":{"type":"boolean","description":"Entitles the regulated user to invite and onboard sales users within their regulated entity"}},"additionalProperties":true,"description":"Sales users permissions"},"templates":{"type":"object","properties":{"canEditEntitlementTemplate":{"type":"boolean","description":"Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity"},"canEditEmailTemplate":{"type":"boolean","description":"Entitles the regulated user to manage invitation email templates for their regulated entity"}},"additionalProperties":true,"description":"Templates permissions"},"parties":{"type":"object","properties":{"canModifyRegulatedEntity":{"type":"boolean","description":"Entitles the regulated user to update their own regulated entity profile"},"canModifyRegulatedEntityLogo":{"type":"boolean","description":"Entitles the regulated user to upload and delete their own regulated entity logo"},"canModifyIntroducingBroker":{"type":"boolean","description":"Entitles the regulated user to create and update introducing broker records within their regulated entity"},"canModifyCompany":{"type":"boolean","description":"Entitles the regulated user to modify company information for their customer accounts"},"canModifyCompanyLogo":{"type":"boolean","description":"Entitles the regulated user to upload and delete company logos for their customer accounts"}},"additionalProperties":true,"description":"Parties permissions"},"my-profile":{"type":"object","properties":{"canModifySelf":{"type":"boolean","description":"Entitles the regulated user to update their own profile details and avatar"},"canModifyMyAvatar":{"type":"boolean","description":"Entitles the regulated user to upload and delete their own avatar"},"canModifyMyUserDetails":{"type":"boolean","description":"Entitles the regulated user to update their own profile details"},"canEditOwnEntitlement":{"type":"boolean","description":"Entitles the regulated user to update their own entitlements"}},"additionalProperties":true,"description":"My profile permissions"},"customers":{"type":"object","properties":{"canModifyCustomer":{"type":"boolean","description":"Entitles the regulated user to create and update customer accounts within their customer companies"},"canDisableCustomer":{"type":"boolean","description":"Entitles the regulated user to disable (suspend) customer users within their regulated entity"},"canEnableCustomer":{"type":"boolean","description":"Entitles the regulated user to re-enable a disabled customer user within their regulated entity"},"canDeleteCustomerPii":{"type":"boolean","description":"Entitles the regulated user to permanently delete a customer user's PII data within their regulated entity"},"canInviteCustomer":{"type":"boolean","description":"Entitles the regulated user to invite and onboard customer users"}},"additionalProperties":true,"description":"Customers permissions"},"api-clients":{"type":"object","properties":{"canManageApiClients":{"type":"boolean","description":"Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration"},"canManageWebhooks":{"type":"boolean","description":"Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery"}},"additionalProperties":true,"description":"Api clients permissions"},"users":{"type":"object","properties":{"canModifyUser":{"type":"boolean","description":"Entitles the regulated user to modify user accounts within their customer companies"},"canDisableRegulatedUser":{"type":"boolean","description":"Entitles the regulated user to disable (suspend) other regulated users within their regulated entity"},"canEnableRegulatedUser":{"type":"boolean","description":"Entitles the regulated user to re-enable a disabled regulated user within their regulated entity"},"canDeleteRegulatedUserPii":{"type":"boolean","description":"Entitles the regulated user to permanently delete a regulated user's PII data within their regulated entity"},"canInviteRegulatedUser":{"type":"boolean","description":"Entitles the regulated user to invite and onboard other regulated users within their organization"},"canResetUserMfa":{"type":"boolean","description":"Entitles the regulated user to reset MFA (TOTP) for users within their regulated entity"}},"additionalProperties":true,"description":"Users permissions"}},"additionalProperties":true,"description":"Permissions for regulated users"},"sales":{"type":"object","properties":{"companies":{"type":"object","properties":{"canDisableCompany":{"type":"boolean","description":"Entitles the sales user to disable (suspend) a company within their introducing broker"},"canEnableCompany":{"type":"boolean","description":"Entitles the sales user to re-enable a disabled company within their introducing broker"},"canDeleteCompanyPii":{"type":"boolean","description":"Entitles the sales user to permanently delete a company's PII data within their introducing broker"}},"additionalProperties":true,"description":"Companies permissions"},"risk-management":{"type":"object","properties":{"canBuyGuard":{"type":"boolean","description":"Entitles the sales user to enter guard trades for their introducing broker's customers"},"canSettleGuard":{"type":"boolean","description":"Entitles the sales user to settle existing guard positions for their introducing broker's customers"},"canExtendGuard":{"type":"boolean","description":"Entitles the sales user to extend guard position expiration dates for their introducing broker's customers"}},"additionalProperties":true,"description":"Risk management permissions"},"invitations":{"type":"object","properties":{"canViewInvitation":{"type":"boolean","description":"Entitles the sales user to view invitations within their introducing broker"},"canManageInvitation":{"type":"boolean","description":"Entitles the sales user to manage and modify invitations within their introducing broker"}},"additionalProperties":true,"description":"Invitations permissions"},"sales-users":{"type":"object","properties":{"canInviteSalesUser":{"type":"boolean","description":"Entitles the sales user to invite and onboard other sales users within their introducing broker"},"canDisableSalesUser":{"type":"boolean","description":"Sales user can disable other sales users within their introducing broker"},"canEnableSalesUser":{"type":"boolean","description":"Sales user can re-enable disabled sales users within their introducing broker"},"canDeleteSalesUserPii":{"type":"boolean","description":"Sales user can permanently delete another sales user's PII data within their introducing broker"}},"additionalProperties":true,"description":"Sales users permissions"},"templates":{"type":"object","properties":{"canEditEmailTemplate":{"type":"boolean","description":"Entitles the sales user to manage invitation email templates"}},"additionalProperties":true,"description":"Templates permissions"},"parties":{"type":"object","properties":{"canModifyIntroducingBroker":{"type":"boolean","description":"Entitles the sales user to modify their introducing broker, including uploading and deleting the IB logo"},"canModifyCompany":{"type":"boolean","description":"Entitles the sales user to modify company information within their introducing broker"},"canModifyCompanyLogo":{"type":"boolean","description":"Entitles the sales user to upload and delete company logos within their introducing broker"}},"additionalProperties":true,"description":"Parties permissions"},"my-profile":{"type":"object","properties":{"canModifySelf":{"type":"boolean","description":"Entitles the sales user to update their own profile details and avatar"},"canModifyMyAvatar":{"type":"boolean","description":"Entitles the sales user to upload and delete their own avatar"},"canModifyMyUserDetails":{"type":"boolean","description":"Entitles the sales user to update their own profile details"},"canEditOwnEntitlement":{"type":"boolean","description":"Entitles the sales user to update their own entitlements"}},"additionalProperties":true,"description":"My profile permissions"},"customers":{"type":"object","properties":{"canModifyCustomer":{"type":"boolean","description":"Entitles the sales user to create and update customer accounts within their introducing broker's companies"},"canDisableCustomer":{"type":"boolean","description":"Sales user can disable customer users within their introducing broker's companies"},"canEnableCustomer":{"type":"boolean","description":"Sales user can re-enable disabled customer users within their introducing broker's companies"},"canDeleteCustomerPii":{"type":"boolean","description":"Sales user can permanently delete a customer user's PII data within their introducing broker"},"canInviteCustomer":{"type":"boolean","description":"Entitles the sales user to invite and onboard customer users within their introducing broker"}},"additionalProperties":true,"description":"Customers permissions"},"users":{"type":"object","properties":{"canModifyUser":{"type":"boolean","description":"Entitles the sales user to modify user accounts within their introducing broker's companies"}},"additionalProperties":true,"description":"Users permissions"}},"additionalProperties":true,"description":"Permissions for sales users"},"customer":{"type":"object","properties":{"risk-management":{"type":"object","properties":{"canBuyGuard":{"type":"boolean","description":"Entitles the customer to enter guard trades for their own company's positions"},"canSettleGuard":{"type":"boolean","description":"Entitles the customer to settle their own company's existing guard positions"},"canExtendGuard":{"type":"boolean","description":"Entitles the customer to extend expiration dates for their own company's guard positions"}},"additionalProperties":true,"description":"Risk management permissions"},"invitations":{"type":"object","properties":{"canViewInvitations":{"type":"boolean","description":"Entitles the customer to view invitations for their company"}},"additionalProperties":true,"description":"Invitations permissions"},"my-profile":{"type":"object","properties":{"canModifyMyAvatar":{"type":"boolean","description":"Entitles the customer to upload, replace, or delete their own avatar image"}},"additionalProperties":true,"description":"My profile permissions"},"users":{"type":"object","properties":{"canInviteUsers":{"type":"boolean","description":"Entitles the customer to invite other users within their company"}},"additionalProperties":true,"description":"Users permissions"}},"additionalProperties":true,"description":"Permissions for customer users"}},"additionalProperties":true,"description":"User permissions organized by scope (internal/regulated/customer) and functional area (risk-management, administration, onboarding). Each permission is an optional boolean flag that controls specific actions the user can perform."},"FXVolSurfaceQuoteDTOModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the vol surface model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currencyPair":"GBPUSD","atmSpot":1.3424,"tenors":{"1D":{"strikes":{"25D_PUT":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"10D_PUT":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"ATMF":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"10D_CALL":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"25D_CALL":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"}}},"1W":{"strikes":{"25D_PUT":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"},"ATMF":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"},"25D_CALL":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"}}}}}},"TradeEventPaymentObligationRuleDTOTrigger":{"type":"object","example":null},"TradeEventProcessingRuleDTORules":{"type":"object","description":"**Extensible JSONB field** - Processing rules definition (JSONB) - field mappings for extracting lot data from events This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"lotMappings":{"amount":{"var":"leg.amount"},"price":{"var":"leg.rate"},"valueDate":{"var":"leg.valueDate"}}}},"CutoffInfoDTOQuote":{"type":"object","description":"**Extensible JSONB field** - Full quote data This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":null},"PriceSourceTreeSourceProperties":{"type":"object","example":null},"FXVolSurfaceQuoteDTOUpsertModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the vol surface model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currencyPair":"GBPUSD","atmSpot":1.3424,"tenors":{"1D":{"strikes":{"25D_PUT":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"10D_PUT":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"ATMF":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"10D_CALL":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"},"25D_CALL":{"bidVol":0.084,"askVol":0.093,"dataSource":"MANUAL"}}},"1W":{"strikes":{"25D_PUT":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"},"ATMF":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"},"25D_CALL":{"bidVol":0.085,"askVol":0.094,"dataSource":"MANUAL"}}}}}},"CompanyDTOPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this company as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Corp","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://acmecorp.example.com","industry":"Financial Services","primary_contact_name":"Jane Smith"}},"EventDTOOldState":{"type":"object","example":null},"InvitationDTOInviterUserPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this user as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"email":"john.doe@example.com","firstName":"John","lastName":"Doe","phone":"+44 20 7946 0958","jobTitle":"Risk Manager","department":"Trading"}},"InvitationDTOPiiData":{"type":"object","description":"**Extensible JSONB field** - Encrypted PII data for the invitee (email, first_name, last_name). Stored on invitation so user creation is deferred to acceptance. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"status":"ENCRYPTED","value":"...","key":"arn:aws:kms:..."}},"ZeroRateCurveDTOModel":{"type":"object","example":null},"GuardMarginScheduleDTOCreateMarginSchedule":{"type":"object","description":"**Extensible JSONB field** - Guard margin schedule as JSON matrix with maturity brackets and amount bands This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"maturityBrackets":[{"maturityPeriod":{"minDays":0,"maxDays":7,"displayName":"≤ 7 days"},"amountBands":[{"amountRange":{"minAmount":0,"maxAmount":50000,"displayName":"≤ £50k"},"marginRate":0.002}]}]}},"IntroducingBrokerDTOCreatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this introducing broker as JSONB (includes name, contact info, auth email domains). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Baumann Partners","primary_contact_name":"Samuel Paine"}},"RegulatedEntityWithRegulatedUsersDTOPiiData":{"type":"object","example":null},"RegulatedEntityDTOUpdatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this regulated entity as JSONB (includes name, regulatory info, address, phone, website, and contact). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Financial Services","regulatory_jurisdiction":"UK","primary_regulatory_reference":"123456","additional_regulatory_references":"SEC: 8-12345, CFTC: 0123456","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://example.com","primary_contact_name":"John Doe"}},"PaymentDTOCreditorDetails":{"type":"object","example":null},"PaymentEventSubscriptionDTOEventTypes":{"type":"object","example":null},"UserDTOPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this user as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"email":"john.doe@example.com","firstName":"John","lastName":"Doe","phone":"+44 20 7946 0958","jobTitle":"Risk Manager","department":"Trading"}},"InvitationDTOInviteeUserPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this user as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"email":"john.doe@example.com","firstName":"John","lastName":"Doe","phone":"+44 20 7946 0958","jobTitle":"Risk Manager","department":"Trading"}},"TradeEventPaymentObligationRuleDTOUpsertTrigger":{"type":"object","example":null},"IntroducingBrokerDTOPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this introducing broker as JSONB (includes name, contact info, auth email domains). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Baumann Partners","primary_contact_name":"Samuel Paine"}},"RegulatedEntityDTOCreatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this regulated entity as JSONB (includes name, regulatory info, address, phone, website, and contact). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Financial Services","regulatory_jurisdiction":"UK","primary_regulatory_reference":"123456","additional_regulatory_references":"SEC: 8-12345, CFTC: 0123456","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://example.com","primary_contact_name":"John Doe"}},"GuardSettlementDTOInternalRefundCalculation":{"type":"object","description":"**Extensible JSONB field** - Full refund calculation including schedule config and per-component breakdown, snapshotted at the time of cancellation. Only populated for cancellation settlements. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":null},"FXVolSurfaceDTOModel":{"type":"object","example":null},"GuardCancellationRefundDTORefundCalculation":{"type":"object","description":"**Extensible JSONB field** - Full refund calculation including schedule and per-component breakdown This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":null},"TradeEventProcessingRuleDTOUpsertRules":{"type":"object","description":"**Extensible JSONB field** - Processing rules definition (JSONB) - field mappings for extracting lot data from events This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"lotMappings":{"amount":{"var":"leg.amount"},"price":{"var":"leg.rate"},"valueDate":{"var":"leg.valueDate"}}}},"CurrencyguardCompanyDTOInternalOperatingHours":{"type":"object","description":"**Extensible JSONB field** - Operating hours for trading operations in JSON format This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"monday":{"open":"09:15:00","close":"16:15:00"},"tuesday":{"open":"09:15:00","close":"16:15:00"},"wednesday":{"open":"09:15:00","close":"16:15:00"},"thursday":{"open":"09:15:00","close":"16:15:00"},"friday":{"open":"09:15:00","close":"16:15:00"}}},"GuardSettlementDTORefundCalculation":{"type":"object","description":"**Extensible JSONB field** - Full refund calculation including schedule config and per-component breakdown, snapshotted at the time of cancellation. Only populated for cancellation settlements. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":null},"CompanyWithCustomersDTOPiiData":{"type":"object","example":null},"ExportEventNewState":{"type":"object","example":null},"CompanyDTOUpdatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this company as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Corp","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://acmecorp.example.com","industry":"Financial Services","primary_contact_name":"Jane Smith"}},"TradeEventPaymentObligationRuleDTOUpsertRules":{"type":"object","example":null},"InterestRateCurveQuoteDTOUpsertModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the ir curve model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currency":"USD","curveType":"ZERO_RATE","tenors":{"1M":{"rate":0.052,"dataSource":"BLOOMBERG"},"3M":{"rate":0.0525,"dataSource":"BLOOMBERG"},"6M":{"rate":0.053,"dataSource":"BLOOMBERG"},"1Y":{"rate":0.054,"dataSource":"BLOOMBERG"},"2Y":{"rate":0.056,"dataSource":"BLOOMBERG"},"5Y":{"rate":0.0595,"dataSource":"BLOOMBERG"},"10Y":{"rate":0.0625,"dataSource":"BLOOMBERG"}}}},"UserDTOUpdatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this user as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"email":"john.doe@example.com","firstName":"John","lastName":"Doe","phone":"+44 20 7946 0958","jobTitle":"Risk Manager","department":"Trading"}},"IntroducingBrokerDTOUpdatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this introducing broker as JSONB (includes name, contact info, auth email domains). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Baumann Partners","primary_contact_name":"Samuel Paine"}},"UserDTOCreatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this user as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"email":"john.doe@example.com","firstName":"John","lastName":"Doe","phone":"+44 20 7946 0958","jobTitle":"Risk Manager","department":"Trading"}},"InterestRateCurveQuoteDTOModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the ir curve model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currency":"USD","curveType":"ZERO_RATE","tenors":{"1M":{"rate":0.052,"dataSource":"BLOOMBERG"},"3M":{"rate":0.0525,"dataSource":"BLOOMBERG"},"6M":{"rate":0.053,"dataSource":"BLOOMBERG"},"1Y":{"rate":0.054,"dataSource":"BLOOMBERG"},"2Y":{"rate":0.056,"dataSource":"BLOOMBERG"},"5Y":{"rate":0.0595,"dataSource":"BLOOMBERG"},"10Y":{"rate":0.0625,"dataSource":"BLOOMBERG"}}}},"GuardMarginScheduleDTOUpdateMarginSchedule":{"type":"object","description":"**Extensible JSONB field** - Guard margin schedule as JSON matrix with maturity brackets and amount bands This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"maturityBrackets":[{"maturityPeriod":{"minDays":0,"maxDays":7,"displayName":"≤ 7 days"},"amountBands":[{"amountRange":{"minAmount":0,"maxAmount":50000,"displayName":"≤ £50k"},"marginRate":0.002}]}]}},"UserDTOPreferences":{"type":"object","description":"**Extensible JSONB field** - UI preferences for this user, namespaced by section. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"tables":{"guard-book":{"pageSize":50}}}},"FXForwardCurveQuoteDTOModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the forward point curve model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currencyPair":"GBPUSD","spot":1.3424,"tenors":{"1D":{"bidPoints":0.0002,"askPoints":0.0004,"dataSource":"BLOOMBERG"},"1W":{"bidPoints":0.0015,"askPoints":0.0018,"dataSource":"BLOOMBERG"},"1M":{"bidPoints":0.005,"askPoints":0.0055,"dataSource":"BLOOMBERG"},"3M":{"bidPoints":0.0145,"askPoints":0.0155,"dataSource":"BLOOMBERG"},"6M":{"bidPoints":0.0285,"askPoints":0.0295,"dataSource":"BLOOMBERG"},"1Y":{"bidPoints":0.0555,"askPoints":0.0575,"dataSource":"BLOOMBERG"}}}},"FXForwardCurveDTOModel":{"type":"object","example":null},"OnboardingEventSubscriptionDTOEventTypes":{"type":"object","description":"**Extensible JSONB field** - Event types this subscriber wants, as a JSON array. NULL means every type. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":["User","Company"]},"PiiDataValue":{"type":"object","example":null},"FXForwardCurveQuoteDTOUpsertModel":{"type":"object","description":"**Extensible JSONB field** - JSON blob representing the forward point curve model This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"currencyPair":"GBPUSD","spot":1.3424,"tenors":{"1D":{"bidPoints":0.0002,"askPoints":0.0004,"dataSource":"BLOOMBERG"},"1W":{"bidPoints":0.0015,"askPoints":0.0018,"dataSource":"BLOOMBERG"},"1M":{"bidPoints":0.005,"askPoints":0.0055,"dataSource":"BLOOMBERG"},"3M":{"bidPoints":0.0145,"askPoints":0.0155,"dataSource":"BLOOMBERG"},"6M":{"bidPoints":0.0285,"askPoints":0.0295,"dataSource":"BLOOMBERG"},"1Y":{"bidPoints":0.0555,"askPoints":0.0575,"dataSource":"BLOOMBERG"}}}},"TradingEventSubscriptionDTOEventTypes":{"type":"object","description":"**Extensible JSONB field** - Event types this subscriber wants, as a JSON array. NULL means every type. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":["Guard","GuardSettlement"]},"GuardMarginScheduleDTOMarginSchedule":{"type":"object","description":"**Extensible JSONB field** - Guard margin schedule as JSON matrix with maturity brackets and amount bands This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"maturityBrackets":[{"maturityPeriod":{"minDays":0,"maxDays":7,"displayName":"≤ 7 days"},"amountBands":[{"amountRange":{"minAmount":0,"maxAmount":50000,"displayName":"≤ £50k"},"marginRate":0.002}]}]}},"TradeEventProcessingRuleDTOUpsertTrigger":{"type":"object","description":"**Extensible JSONB field** - JsonLogic trigger expression (JSONB) This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"!=":[{"var":"new.tradeType"},null]}},"CompanyDTOCreatePiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this company as encrypted JSON. This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Corp","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://acmecorp.example.com","industry":"Financial Services","primary_contact_name":"Jane Smith"}},"TradeEventProcessingRuleDTOTrigger":{"type":"object","description":"**Extensible JSONB field** - JsonLogic trigger expression (JSONB) This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"!=":[{"var":"new.tradeType"},null]}},"CurrencyguardCompanyDTOUpdateOperatingHours":{"type":"object","description":"**Extensible JSONB field** - Operating hours for trading operations in JSON format This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"monday":{"open":"09:15:00","close":"16:15:00"},"tuesday":{"open":"09:15:00","close":"16:15:00"},"wednesday":{"open":"09:15:00","close":"16:15:00"},"thursday":{"open":"09:15:00","close":"16:15:00"},"friday":{"open":"09:15:00","close":"16:15:00"}}},"TradeEventPaymentObligationRuleDTORules":{"type":"object","example":null},"EventDTONewState":{"type":"object","example":null},"CurrencyguardCompanyDTOOperatingHours":{"type":"object","description":"**Extensible JSONB field** - Operating hours for trading operations in JSON format This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"monday":{"open":"09:15:00","close":"16:15:00"},"tuesday":{"open":"09:15:00","close":"16:15:00"},"wednesday":{"open":"09:15:00","close":"16:15:00"},"thursday":{"open":"09:15:00","close":"16:15:00"},"friday":{"open":"09:15:00","close":"16:15:00"}}},"PriceSourceTreeSourceOperationalState":{"type":"object","example":null},"RegulatedEntityDTOPiiData":{"type":"object","description":"**Extensible JSONB field** - The PII data for this regulated entity as JSONB (includes name, regulatory info, address, phone, website, and contact). This field accepts any valid JSON structure and can be extended with additional properties as needed. Note: While the structure is extensible, known fields shown in the example are subject to application validation.","example":{"name":"Acme Financial Services","regulatory_jurisdiction":"UK","primary_regulatory_reference":"123456","additional_regulatory_references":"SEC: 8-12345, CFTC: 0123456","registered_company_number":"12345678","address":{"address_line1":"123 Financial Street","address_line2":"Suite 456","city":"London","postcode":"EC1A 1BB","country":"United Kingdom"},"phone_number":"+44 20 7946 0958","website":"https://example.com","primary_contact_name":"John Doe"}}},"securitySchemes":{"bearerScheme":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"entitlementsScheme":{"type":"oauth2","description":"Fine-grained entitlement required to call this endpoint. Documentation only — actual enforcement is via JWT claims.","flows":{"implicit":{"authorizationUrl":"https://auth.currencyguard.com/oauth2/authorize","scopes":{"internal.my-profile.canModifyMyAvatar":"Entitles the internal user to upload and delete their own avatar","internal.my-profile.canModifyMyUserDetails":"Entitles the internal user to update their own profile details","internal.my-profile.canEditOwnEntitlement":"Entitles the internal user to modify their own entitlements","internal.risk-management.canEnterFxOptionTrade":"Entitles the internal user to enter FX option trades on behalf of customers","internal.risk-management.canPriceOptions":"Entitles the internal user to reprice options and run what-if option valuation scenarios","internal.risk-management.canEnterFxCashTrade":"Entitles the internal user to enter FX cash trades on behalf of customers","internal.risk-management.canBuyGuard":"Entitles the internal user to enter guard trades on behalf of customers","internal.risk-management.canSettleGuard":"Entitles the internal user to settle existing guard positions","internal.risk-management.canExtendGuard":"Entitles the internal user to extend guard position expiration dates","internal.risk-management.canVoidGuard":"Entitles the internal user to void a guard whose fee was never received, unwinding its hedge","internal.parties.canModifyIntroducingBroker":"Entitles the internal user to create and update introducing broker records","internal.parties.canModifyRegulatedEntity":"Entitles the internal user to create, update, and manage regulated entities","internal.parties.canModifyRegulatedEntityLogo":"Entitles the internal user to upload and delete logos for regulated entities","internal.parties.canModifyCompany":"Entitles the internal user to create, update, and manage company information","internal.parties.canModifyCurrencyGuardCompany":"Entitles the internal user to update CurrencyGuard company configuration","internal.market-data.canModifySpotFX":"Entitles the internal user to configure spot FX price sources, set manual prices, and manage spot quote data","internal.market-data.canModifyForwardCurves":"Entitles the internal user to configure forward curve price sources and manage forward curve quote data","internal.market-data.canModifyIRCurves":"Entitles the internal user to configure interest rate curve price sources and manage IR curve quote data","internal.market-data.canModifyVolSurfaces":"Entitles the internal user to configure vol surface price sources and manage vol surface quote data","internal.market-data.canModifyHistoricFXPrices":"Entitles the internal user to sync, upload, and delete historic FX price data","internal.market-data.canAuthenticateSaxo":"Entitles the internal user to manage Saxo authentication sessions (login, logout, refresh)","internal.reference-data.canModifyCurrency":"Entitles the internal user to create, update, and manage currency configurations","internal.reference-data.canModifyCalendar":"Entitles the internal user to create, update, and manage trading calendars","internal.reference-data.canModifyCurrencyPair":"Entitles the internal user to create and update tradeable currency pairs","internal.reference-data.canModifyTradingHours":"Entitles the internal user to set the trading enabled and outside-hours trading flags","internal.reference-data.canModifyGuardMarginSchedule":"Entitles the internal user to create and update guard margin schedules","internal.reference-data.canModifyCounterparties":"Entitles the internal user to create and update counterparty records","internal.ledger.canModifyScheduler":"Entitles the internal user to schedule, pause, resume, and trigger scheduled jobs in the ledger domain","internal.ledger.canModifyChartOfAccounts":"Entitles the internal user to create, update, and deactivate chart of accounts entries","internal.ledger.canModifyAccountPeriods":"Entitles the internal user to create, update, and manage account periods and month-end close workflows","internal.ledger.canEnterJournals":"Entitles the internal user to create, batch-create, and reverse journal entry pairs","internal.system.canModifyTradingConfigs":"Entitles the internal user to modify trading domain configuration settings","internal.system.canModifyOnboardingConfig":"Entitles the internal user to update onboarding configuration settings","internal.system.canModifyTenantPerimeters":"Entitles the internal user to ringfence and merge tenants, replace a perimeter's encryption key, and set ringfencing policy. Every one of these re-encrypts a tenant's data and provisions or retires AWS resources, but none destroys anything","internal.system.canShredTenantPerimeterKey":"Entitles the internal user to destroy a perimeter's encryption key, making every row, document and backup belonging to that tenant permanently unreadable, and to cancel a destruction within its window. This is the tenant-wide counterpart of the canDelete*Pii entitlements: those erase one person's data from the tables that hold it, whereas this erases everyone in the perimeter at once and reaches copies no delete statement can — backups, replicas, exports. Held apart from the other perimeter operations because it is the only one with no way back","internal.system.canImportTrades":"Entitles the internal user to bulk-import trades from a JSON export, writing directly into the trade book and bypassing the normal booking and pricing path. The counterpart of canDeleteAllTrades, with the same blast radius in the opposite direction","internal.system.canAcceptEventDeliveries":"Entitles the caller to submit batches of domain events into a consuming domain. Held by the system account rather than by people: it is what lets the trading and ledger hexagons receive pushed trade, trade-reference, and onboarding events. Revoking it halts cross-domain sync","internal.system.canModifyScheduler":"Entitles the internal user to schedule, pause, resume, and trigger scheduled jobs in the trading domain","internal.system.canModifySystemClock":"Entitles the internal user to start, stop, rewind, and otherwise manipulate the system clock","internal.system.canModifyTradeEventProcessingRules":"Entitles the internal user to create, update, and delete trade event processing rules and rule versions","internal.payments.canRaisePayments":"Entitles the internal user to raise payments and allocate them against debts — the MAKER half of maker-checker","internal.payments.canApprovePayments":"Entitles the internal user to APPROVE a payment. Deliberately separate from raising one: granting both to the same person defeats maker-checker at the entitlement level, before the checker <> maker rule ever gets a chance to bite","internal.payments.canRaiseManualObligations":"Entitles the internal user to raise a debt by hand against a counterparty — one no trade event raises, booked to the ledger on creation","internal.payments.canWriteOffObligations":"Entitles the internal user to write off part or all of a debt owed to CurrencyGuard, or to reverse an earlier write-off. Separate from raising payments: giving up money owed is a decision, not cash application","internal.payments.canReprocessObligations":"Entitles the internal user to reprocess one Guard's payment obligations — re-run the current rules and reconcile against what exists. Read-only preview; it never rewrites a debt money has moved against","internal.system.canModifyObligationRules":"Entitles the internal user to create, update, and deactivate settlement obligation rules — which decide what debt a trade event raises, and for how much","internal.system.canResubmitTradeEventProcessing":"Entitles the internal user to rewind event sequences, discharge and retry failed trade event processing","internal.system.canDeleteAllTrades":"Entitles the internal user to permanently delete all trading data (destructive, dev/test only)","internal.system.canModifyMfaSettings":"Entitles the internal user to enable or disable MFA (TOTP) on Cognito user pools","internal.users.canModifyUser":"Entitles the internal user to create, update, and manage user accounts","internal.users.canDisableInternalUser":"Entitles the internal user to disable (suspend) other internal users","internal.users.canEnableInternalUser":"Entitles the internal user to re-enable a disabled internal user","internal.users.canDeleteInternalUserPii":"Entitles the internal user to permanently delete an internal user's PII data","internal.users.canDisableRegulatedUser":"Entitles the internal user to disable (suspend) regulated users","internal.users.canEnableRegulatedUser":"Entitles the internal user to re-enable a disabled regulated user","internal.users.canDeleteRegulatedUserPii":"Entitles the internal user to permanently delete a regulated user's PII data","internal.users.canInviteInternalUser":"Entitles the internal user to invite and onboard other internal CurrencyGuard users","internal.users.canInviteRegulatedUser":"Entitles the internal user to invite and onboard regulated users","internal.users.canResetUserMfa":"Entitles the internal user to reset MFA (TOTP) for any user, forcing re-enrollment on next login","internal.sales-users.canDisableSalesUser":"Entitles the internal user to disable (suspend) sales users","internal.sales-users.canEnableSalesUser":"Entitles the internal user to re-enable a disabled sales user","internal.sales-users.canDeleteSalesUserPii":"Entitles the internal user to permanently delete a sales user's PII data","internal.customers.canDisableCustomer":"Entitles the internal user to disable (suspend) customer users","internal.customers.canEnableCustomer":"Entitles the internal user to re-enable a disabled customer user","internal.customers.canDeleteCustomerPii":"Entitles the internal user to permanently delete a customer user's PII data","internal.invitations.canViewAllInvitation":"Entitles the internal user to view all invitations across the entire system","internal.invitations.canManageAllInvitation":"Entitles the internal user to manage and modify all invitations across the entire system","internal.templates.canEditEntitlementTemplate":"Entitles the internal user to create, update, and manage entitlements templates","internal.templates.canEditEmailTemplate":"Entitles the internal user to create, update, and manage invitation email templates","internal.api-clients.canManageApiClients":"Entitles the internal user to create, view, rotate, and delete system-level API clients","internal.api-clients.canManageWebhooks":"Entitles the internal user to register, renew, suspend, and delete webhook subscriptions against the internal trade and onboarding event streams. The internal counterpart of regulated.api-clients.canManageWebhooks. Also held by the system account, which registers and renews the cross-domain sync subscriptions on startup","internal.api-clients.canReplayWebhooks":"Entitles the internal user to restate a webhook subscription's cursor and replay historic events. Separated from canManageWebhooks because replay re-delivers events that have already been consumed, which double-processes on any non-idempotent consumer","regulated.my-profile.canModifySelf":"Entitles the regulated user to update their own profile details and avatar","regulated.my-profile.canModifyMyAvatar":"Entitles the regulated user to upload and delete their own avatar","regulated.my-profile.canModifyMyUserDetails":"Entitles the regulated user to update their own profile details","regulated.my-profile.canEditOwnEntitlement":"Entitles the regulated user to update their own entitlements","regulated.risk-management.canBuyGuard":"Entitles the regulated user to enter guard trades for their customers","regulated.risk-management.canSettleGuard":"Entitles the regulated user to settle existing guard positions for their customers","regulated.risk-management.canExtendGuard":"Entitles the regulated user to extend guard position expiration dates for their customers","regulated.parties.canModifyRegulatedEntity":"Entitles the regulated user to update their own regulated entity profile","regulated.parties.canModifyRegulatedEntityLogo":"Entitles the regulated user to upload and delete their own regulated entity logo","regulated.parties.canModifyIntroducingBroker":"Entitles the regulated user to create and update introducing broker records within their regulated entity","regulated.parties.canModifyCompany":"Entitles the regulated user to modify company information for their customer accounts","regulated.parties.canModifyCompanyLogo":"Entitles the regulated user to upload and delete company logos for their customer accounts","regulated.companies.canDisableCompany":"Entitles the regulated user to disable (suspend) a company within their regulated entity","regulated.companies.canEnableCompany":"Entitles the regulated user to re-enable a disabled company within their regulated entity","regulated.companies.canDeleteCompanyPii":"Entitles the regulated user to permanently delete a company's PII data within their regulated entity","regulated.system.canModifyMfaSettings":"Entitles the regulated user to enable or disable MFA (TOTP) on their regulated entity's Cognito user pool","regulated.users.canModifyUser":"Entitles the regulated user to modify user accounts within their customer companies","regulated.users.canDisableRegulatedUser":"Entitles the regulated user to disable (suspend) other regulated users within their regulated entity","regulated.users.canEnableRegulatedUser":"Entitles the regulated user to re-enable a disabled regulated user within their regulated entity","regulated.users.canDeleteRegulatedUserPii":"Entitles the regulated user to permanently delete a regulated user's PII data within their regulated entity","regulated.users.canInviteRegulatedUser":"Entitles the regulated user to invite and onboard other regulated users within their organization","regulated.users.canResetUserMfa":"Entitles the regulated user to reset MFA (TOTP) for users within their regulated entity","regulated.sales-users.canModifySalesUser":"Regulated user can create/update sales users (CRM-style, no invitation)","regulated.sales-users.canDisableSalesUser":"Entitles the regulated user to disable (suspend) sales users within their regulated entity","regulated.sales-users.canEnableSalesUser":"Entitles the regulated user to re-enable a disabled sales user within their regulated entity","regulated.sales-users.canDeleteSalesUserPii":"Entitles the regulated user to permanently delete a sales user's PII data within their regulated entity","regulated.sales-users.canInviteSalesUser":"Entitles the regulated user to invite and onboard sales users within their regulated entity","regulated.customers.canModifyCustomer":"Entitles the regulated user to create and update customer accounts within their customer companies","regulated.customers.canDisableCustomer":"Entitles the regulated user to disable (suspend) customer users within their regulated entity","regulated.customers.canEnableCustomer":"Entitles the regulated user to re-enable a disabled customer user within their regulated entity","regulated.customers.canDeleteCustomerPii":"Entitles the regulated user to permanently delete a customer user's PII data within their regulated entity","regulated.customers.canInviteCustomer":"Entitles the regulated user to invite and onboard customer users","regulated.invitations.canViewInvitation":"Entitles the regulated user to view invitations within their scope of responsibility","regulated.invitations.canManageInvitation":"Entitles the regulated user to manage and modify invitations within their scope of responsibility","regulated.api-clients.canManageApiClients":"Entitles the regulated user to create, view, rotate, and delete API clients for server-to-server integration","regulated.api-clients.canManageWebhooks":"Entitles the regulated user to create, view, update, rotate, delete, and replay webhook subscriptions for B2B event delivery","regulated.templates.canEditEntitlementTemplate":"Entitles the regulated user to create, update, and manage entitlements templates for their regulated entity","regulated.templates.canEditEmailTemplate":"Entitles the regulated user to manage invitation email templates for their regulated entity","sales.my-profile.canModifySelf":"Entitles the sales user to update their own profile details and avatar","sales.my-profile.canModifyMyAvatar":"Entitles the sales user to upload and delete their own avatar","sales.my-profile.canModifyMyUserDetails":"Entitles the sales user to update their own profile details","sales.my-profile.canEditOwnEntitlement":"Entitles the sales user to update their own entitlements","sales.risk-management.canBuyGuard":"Entitles the sales user to enter guard trades for their introducing broker's customers","sales.risk-management.canSettleGuard":"Entitles the sales user to settle existing guard positions for their introducing broker's customers","sales.risk-management.canExtendGuard":"Entitles the sales user to extend guard position expiration dates for their introducing broker's customers","sales.parties.canModifyIntroducingBroker":"Entitles the sales user to modify their introducing broker, including uploading and deleting the IB logo","sales.parties.canModifyCompany":"Entitles the sales user to modify company information within their introducing broker","sales.parties.canModifyCompanyLogo":"Entitles the sales user to upload and delete company logos within their introducing broker","sales.companies.canDisableCompany":"Entitles the sales user to disable (suspend) a company within their introducing broker","sales.companies.canEnableCompany":"Entitles the sales user to re-enable a disabled company within their introducing broker","sales.companies.canDeleteCompanyPii":"Entitles the sales user to permanently delete a company's PII data within their introducing broker","sales.users.canModifyUser":"Entitles the sales user to modify user accounts within their introducing broker's companies","sales.sales-users.canInviteSalesUser":"Entitles the sales user to invite and onboard other sales users within their introducing broker","sales.sales-users.canDisableSalesUser":"Sales user can disable other sales users within their introducing broker","sales.sales-users.canEnableSalesUser":"Sales user can re-enable disabled sales users within their introducing broker","sales.sales-users.canDeleteSalesUserPii":"Sales user can permanently delete another sales user's PII data within their introducing broker","sales.customers.canModifyCustomer":"Entitles the sales user to create and update customer accounts within their introducing broker's companies","sales.customers.canDisableCustomer":"Sales user can disable customer users within their introducing broker's companies","sales.customers.canEnableCustomer":"Sales user can re-enable disabled customer users within their introducing broker's companies","sales.customers.canDeleteCustomerPii":"Sales user can permanently delete a customer user's PII data within their introducing broker","sales.customers.canInviteCustomer":"Entitles the sales user to invite and onboard customer users within their introducing broker","sales.invitations.canViewInvitation":"Entitles the sales user to view invitations within their introducing broker","sales.invitations.canManageInvitation":"Entitles the sales user to manage and modify invitations within their introducing broker","sales.templates.canEditEmailTemplate":"Entitles the sales user to manage invitation email templates","customer.my-profile.canModifyMyAvatar":"Entitles the customer to upload, replace, or delete their own avatar image","customer.risk-management.canBuyGuard":"Entitles the customer to enter guard trades for their own company's positions","customer.risk-management.canSettleGuard":"Entitles the customer to settle their own company's existing guard positions","customer.risk-management.canExtendGuard":"Entitles the customer to extend expiration dates for their own company's guard positions","customer.users.canInviteUsers":"Entitles the customer to invite other users within their company","customer.invitations.canViewInvitations":"Entitles the customer to view invitations for their company"}}}}}},"x-tagGroups":[{"tags":["ApiClient","ServerTime","ProblemTypes","AuthPoolConfig","UIConfig"],"name":"Getting started"},{"tags":["Guard","GuardQuote","GuardSettlement","GuardConfirmation","GuardPricing"],"name":"Guards"},{"tags":["SpotRates","MarketStatus","PriceHistory","HistoricPerformance"],"name":"Market data"},{"tags":["Currency","CurrencyPair","Calendar","CalendarDate","TradingCalendar","Configuration"],"name":"Reference data"},{"tags":["Webhooks","Messaging","SubscriptionMessages"],"name":"Events and streaming"},{"tags":["RegulatedEntity","IntroducingBroker","Company","CustomerManagement","User","SalesUserManagement","CurrencyguardCompany"],"name":"Organisations and people"},{"tags":["Invitation","InvitationTemplate","EntitlementsTemplate","Offboarding","CompanyOffboarding"],"name":"Access and onboarding"},{"tags":["Documents","ConfirmationTemplate","Reports","TradeExport"],"name":"Documents and reporting"},{"tags":["Payment Rails"],"name":"Other"}]}