1. Sokin MCP
Sokin Embedded API
  • Getting Started
    • Sokin Definitions
    • Guides
      • Authentication
      • Receiving Payments
      • FX Payments
      • Payments
      • Unfunded Payments
      • Unfunded FX Payments
      • Webhooks
      • Corporate Onboarding
        • Data Requirements
        • Step 1: Create a corporate profile
        • Step 2: Add associates
        • Step 3: Add a parent entity (if applicable)
        • Step 4: Upload company documents
        • Step 5: Upload associate documents
        • Real-time Status Updates via Webhook
        • Conditional Step: Upload Parent Entity documents (if applicable)
        • Step 6: Finalise onboarding submission
        • Uploading supporting documents using Pre-signed URLs
        • Onboarding Reference Data
        • Onboarding Models
          • Data-Only model
          • Supported Jurisdictions & National ID Requirements
      • Sokin MCP
        • Sokin MCP - Setup and Usage Guide
        • Sokin MCP - Tool Guide
        • Sokin MCP - Technical Docs
  • Authentication
    • Get Token
      POST
    • Schemas
      • TokenResponse
  • Corporates
    • v2025-12-01
      • Create a new Corporate
      • Add a parent entity (corporate associate) to an onboarding request
      • Add an associate to a corporate onboarding request
      • Request pre-signed URLs for onboarding document uploads
      • Request pre-signed URLs for parent entity document uploads
      • Request pre-signed URLs for associate document uploads
      • Finalise corporate onboarding submission
    • Schemas
      • CreateCorporateRequest
      • UboDetails
      • OwnershipType
      • AssociateDocumentPresignedUrlResponse
      • AddOnboardingDocumentsRequest
      • MessageResponse
      • AssociateDocumentPresignedUrlResponseItem
      • ErrorDetail
      • CorporateAssociateType
      • ErrorResponse
      • PresignedUrlResponse
      • AddressTypeEnum
      • FinaliseSubmissionRequest
      • AddParentEntityRequest
      • CreateCorporateResponse
      • AssociateIdentityType
      • ApiResponse[AddOnboardingDocumentsResponse]
      • CorporateCategories
      • AddOnboardingDocumentsResponse
      • ApiResponse[CorporateDetailResponse]
      • ApiResponse[AddAssociateDocumentsResponse]
      • AddParentEntityDocumentsRequest
      • AddAssociateDocumentsResponse
      • AddParentEntityResponse
      • AddIndividualAssociateRequest
      • ApiResponse[CreateCorporateResponse]
      • AddIndividualAssociateResponse
      • CorporateDetailResponse
      • AssociateType
      • ApiResponse[AddParentEntityResponse]
      • NumericRange
      • ApiResponse[AddIndividualAssociateResponse]
      • MoneyRange
      • AddAssociateDocumentsRequest
      • FinaliseSubmissionResponse
      • AssociateIdentityType
  • Corporate Currency Accounts
    • v2025-12-01
      • Get Corporate Currency Accounts
      • Get Cca Ledger Items
      • Get Corporate Currency Account By Reference
    • Schemas
      • GetCCAByReferenceResponse
      • GetCCAsResponseItem
      • PaginatedApiResponse[GetCCALedgerItemsResponseItem]
      • ErrorDetail
      • PageInfo
      • SearchCCALedgersResponseItem
      • PaginationInfo
      • GetCCAUnifiedBalanceResponse
      • PaginatedApiResponse[SearchCCALedgersResponseItem]
      • ErrorResponse
      • ApiResponse[GetCCAUnifiedBalanceResponse]
      • SearchCCALedgersRequest
      • PaginatedApiResponse[GetCCAsResponseItem]
      • ApiResponse[GetCCAByReferenceResponse]
      • PaginationInfo
      • SearchCCALedgersPagination
      • GetCCAByReferenceResponsePayInDetail
      • CurrencyCode
      • GetCCALedgerItemsResponseItem
      • PaginationInfo
  • Beneficiaries
    • v2025-12-01
      • Get Beneficiary Schema
      • Create Beneficiary
      • Get Beneficiary List
      • Get Beneficiary Details
      • Delete Beneficiary
      • Validate Beneficiary
      • Validate Beneficiaries
      • List Financial Institutions
      • List Financial Institution Branches
    • Schemas
      • ProviderBankIdentifierRequest
      • ErrorDetail
      • FinancialInstitutionReferenceResponse
      • PaymentRail
      • ApiResponse[list[FinancialInstitutionReferenceResponse]]
      • DeleteBeneficiaryData
      • AddressResponse
      • BeneficiarySchemaFieldCondition
      • ApiResponse[list[BankCountryCurrencyResponse]]
      • PageInfo
      • CurrencyCode
      • BeneficiarySchemaField
      • BeneficiaryValidationResultResponse
      • StateOrProvince
      • ApiResponse[BeneficiaryResponse]
      • BeneficiaryField
      • BeneficiaryStatus
      • DestinationResponse
      • ValidationStatus
      • BeneficiaryType
      • PaymentMethodType
      • PaginatedApiResponse[FinancialInstitutionBranchReferenceResponse]
      • ValidateBeneficiariesRequest
      • ApiResponse[ValidateBatchBeneficiariesResponse]
      • CompanyDetailsResponse
      • SchemaFieldVisibility
      • FieldErrorResponse
      • StateOrProvince
      • ValidateBeneficiaryRequest
      • ErrorResponse
      • FieldType
      • VirtualAccountDestinationRequest
      • ApiResponse[DeleteBeneficiaryData]
      • SokinInternalDestinationRequest
      • GetBeneficiaryFieldsResponse
      • BeneficiaryResponse
      • ApiResponse[ValidateBeneficiaryResponse]
      • FinancialInstitutionBranchReferenceResponse
      • IdentifierType
      • CreateBeneficiaryRequest
      • IndividualDetailsRequest
      • SchemaFieldType
      • TransactionTypeEnum
      • CryptoDestinationRequest
      • AccountType
      • BeneficiaryValidationPayload
      • ApiResponse[GetBeneficiaryFieldsResponse]
      • AccountNumberType
      • BankAccountCategory
      • ApiResponse[GetBeneficiarySchemaResponse]
      • PaginatedApiResponse[BeneficiaryResponse]
      • ApiResponse[list[BankCountryResponse]]
      • AddressRequest
      • PaginationInfo
      • RegionalHints
      • BankCountryCurrencyResponse
      • PaginationInfo
      • ValidateBatchBeneficiariesResponse
      • CreateExternalBeneficiaryData
      • FinancialInstitutionRequest
      • ApiResponse[CreateExternalBeneficiaryData]
      • CompanyDetailsRequest
      • BankCountryResponse
      • CreateExternalBeneficiaryRequest
      • BankAccountDestinationRequest
      • IndividualDetailsResponse
      • BeneficiarySchemaCondition
      • BeneficiaryDestinationValidationResult
      • BeneficiaryEntityType
      • GetBeneficiarySchemaResponse
      • ETransferDestinationRequest
      • ValidateBeneficiaryResponse
      • RoutingCodeRequest
      • ApiResponse[BeneficiaryDetails]
      • BeneficiaryListItem
      • PaginatedApiResponse[BeneficiaryListItem]
      • StateOrProvince
      • PaginationInfo
      • PaginatedBeneficiaryFieldsResponse
      • BeneficiaryDetails
      • RoutingScheme
      • ApiResponse[ListFinancialInstitutionsResponse]
      • ListFinancialInstitutionsResponse
  • Instruction Requests
    • v2025-12-01
      • Create Payment Instruction Request
      • Create Fx Instruction Request
      • Create Fx Payment Instruction Request
      • Create Unfunded Payment Instruction Request
      • Create Unfunded Fx Payment Instruction Request
      • Get Instruction Request By Reference
    • Schemas
      • ApiResponse[GetInstructionRequestResponse]
      • ValidateInstructionCreationRequest
      • ErrorDetail
      • InstructionType
      • CreateInstructionRequestResponse
      • ApiResponse[CreateInstructionRequestResponse]
      • ValidateInstructionCreationResponse
      • CreateFxPaymentInstructionRequest
      • FeeBreakdownResponse
      • ErrorResponse
      • CreateUnfundedPaymentInstructionRequest
      • CreateUnfundedFxPaymentInstructionRequest
      • ApiResponse[list[str]]
      • GetInstructionRequestResponse
      • PaymentPurpose
      • CreatePaymentInstructionRequest
      • CreateFXInstructionRequest
      • ApiResponse[ValidateInstructionCreationResponse]
      • CreateSokinDirectInstructionRequest
  • Instructions
    • v2025-12-01
      • Get Instruction By Reference
    • Schemas
      • GetInstructionResponse
      • PaginatedApiResponse[InstructionListResponseItem]
      • ApiResponse[GetInstructionResponse]
      • PaginationInfo
      • ErrorResponse
      • ErrorDetail
      • PageInfo
      • InstructionListResponseItem
      • PaginationInfo
  • Foreign Exchange
    • v2025-12-01
      • Get Fx Rate
    • v2026-08-01
      • Request FX Quote
    • Schemas
      • ApiResponse[FxRateData]
      • CurrencyCode
      • FixedSide
      • FxRateRequest
      • FXValidityPeriod
      • FxRateData
      • ErrorResponse
      • ErrorDetail
      • FXTenorType
      • RequestFxQuoteRequest
      • CreateQuoteResponse
      • ApiResponse[CreateQuoteResponse]
  • Webhooks
    • v2025-12-01
      • Create Subscription
      • Update Subscription
      • Get Subscription By Id
      • Delete Subscription
      • Update Subscription Status
      • List Notification Logs
      • Retry Notification
    • Schemas
      • ApiResponse[UpdateSubscriptionResponse]
      • PaginationInfo
      • SubscriptionCreateOrUpdate
      • NotificationStatus
      • NotificationAttemptResponse
      • SubscribableWebhookEventType
      • SubscriptionStatusUpdate
      • ApiResponse[CreateSubscriptionResponse]
      • UpdateSubscriptionResponse
      • PaginatedApiResponse[NotificationLogResponse]
      • PaginationInfo
      • ErrorResponse
      • ErrorDetail
      • PageInfo
      • CreateSubscriptionResponse
      • NotificationLogResponse
      • WebhookSubscription
  • Payment Acceptance
    • Payment Acceptance
  1. Sokin MCP

Sokin MCP - Tool Guide

Sokin MCP — Tool Guide#

Disclaimer: The MCP functionality described on this page is currently
available only in Sokin's UAT environment and is not yet available to all
customers across all live regions. This is a temporary limitation, and Sokin
plans to make these capabilities available to all customers across its live
regions in the near future. Please contact Sokin for further information
regarding availability and access.
Every tool the Sokin MCP server offers: what it is for, what it needs from
you, and an example of what comes back. 23 tools, one section each, all in
the same shape so you can skim or search the page.
Start with the Sokin MCP — Setup and Usage Guide if you have not connected a
client yet.
This page assumes you are connected and the balances prompt
worked.
You do not call these tools yourself. You ask your AI client for something in
plain English — "what are my balances", "show me last month's transactions on
the GBP account" — and it picks the tools and fills in the details. The
examples below show what it sends and receives, so you can recognise what is
happening and tell whether you got what you asked for.
Everything here describes the UAT (test) environment.

Jump to#

All 23 tools — the full list
What you can ask for — the tools grouped by job
Reading a result
Which tools your client can use
Moving money — the two flows that do, and how they ask first
The tools, one by one
Starter project ideas

All 23 tools#

In the order they appear below.
ToolWhat it is for
list_corporatesWhich companies your login can act for
list_accountsA company's currency accounts and balances
get_accountOne account in full, including pay-in details
get_account_ledgerTransaction history for an account
list_beneficiariesWho a company can pay
get_beneficiaryOne payee in full, with account details and verification
get_beneficiary_schemaWhat details a new payee needs
list_financial_institutionsBanks available when setting up a payee
list_financial_institution_branchesA bank's branches and routing numbers
list_instructionsPayments and conversions, listed
get_instructionOne payment or conversion in full
get_instruction_requestHow a submitted payment actually turned out
validate_payment_instructionCheck a payment without sending it
create_payment_instructionPrepare a payment for review. Sends nothing
submit_payment_instructionSends a real payment
create_fx_payment_instructionPrepare a pay-in-another-currency payment. Sends nothing
submit_fx_payment_instructionSends a real payment, converting as it goes
get_fx_quoteAsk what an exchange rate is
create_fx_quoteCreate a real, short-lived rate. Moves no money
settle_fx_quoteConverts real money between your own accounts
visualizeDraw a diagram or chart in the chat
get_documentation_linksWhere Sokin's documentation lives
play_cheetah_dashAn arcade game, in the chat

What you can ask for#

If you want toThe tools behind it
See which companies you can act forlist_corporates
See balances across accountslist_accounts, get_account
See transaction historyget_account_ledger
Look up who you can paylist_beneficiaries
Look up a bank or branchlist_financial_institutions, list_financial_institution_branches
Check on payments already madelist_instructions, get_instruction, get_instruction_request
Check a payment before sending itvalidate_payment_instruction
Send a paymentcreate_payment_instruction, then submit_payment_instruction
Get an exchange rateget_fx_quote
Convert between your own accountscreate_fx_quote, then settle_fx_quote
Draw a chart or diagram of a resultvisualize
Find Sokin's documentationget_documentation_links
19 of the 23 only read data. The other four change something, and three of
those move real money — your client asks you to confirm before any of them
runs. See Moving money.

Reading a result#

Every tool answers twice, in the same reply:
A sentence or a table — what your AI client reads out to you.
A structured payload — the same facts as data, for code to use.
The examples below show both. If you are just using a chat client, the first
one is what you will see; the second is there so a developer can check the
exact shape.
Two things worth knowing whatever you are building:
A failure comes back as an error with no structured payload at all. If
you are writing code, check for the error flag before reading the data, and
do not try to match on the wording of the message.
By default the structured payload is trimmed to the useful fields.
Clients can ask for the raw, fuller version instead; the Technical Docs
page documents that and exactly what each tool adds.
Four tools return long lists a page at a time — get_account_ledger,
list_instructions, list_beneficiaries and
list_financial_institution_branches. When there is more, the result says so
and carries a token for the next page; your client handles this for you.

Which tools your client can use#

Some tools render an interactive card in the chat rather than plain
text — a payment review card with Approve and Cancel, an FX card with a live
countdown, a chart, a game. Claude renders these. Replit and ChatGPT do not,
today.
This decides what you can do, not just how it looks:
Client with cardsClient without
All the read-only toolsWorkWork
get_fx_quoteInteractive quote cardA real rate, plus a link to the Sokin portal to trade
create_fx_quote, settle_fx_quoteDriven by the card's buttonsNot available
Paying a beneficiaryReview card with ApproveWorks — the figures and key come back as text, and you confirm in the chat
visualize, play_cheetah_dashRenderReturn their content as text
On a client without cards, treat the read-only tools and get_fx_quote as
what you can use
— including validate_payment_instruction, which is a
genuine dry run and safe to build on.
The money flows are not blocked in the same way, and the difference matters if
you are writing a client:
Converting between your own accounts is refused outright.
settle_fx_quote checks the session's declared card support before anything
else and fails closed, so a cardless session cannot convert currency however
it calls the tool. create_fx_quote does the same. Send those users to the
Sokin portal.
Paying a beneficiary works fine without a card, and is meant to. The
prepare step returns the figures, the idempotency key and (for an FX payment)
the quote id in the text, and asks the assistant to read them back and get
your explicit approval in the chat before submitting. So a plain-chat
prepare → confirm → submit flow is the supported path on those clients, not
a workaround.
Where the human control actually sits for a payment. Not in the card, and
not in a capability check — the server performs none for either payment pair.
It sits in two places: your client's own confirmation prompt before a
destructive tool, and the company's own approval rules in the Sokin B2B
portal, which decide whether a submitted payment still needs a human sign-off.
Both are load-bearing rather than decorative.
Checking your client: if create_fx_quote and settle_fx_quote are absent
from its tool list, it definitely did not declare card support. Their presence
does not prove the opposite — the server hides them only from a session it
knows lacks support, and shows everything when it cannot tell, so an
uninitialised client can see them and still be refused. The reliable signal is
whether a card actually renders.

Moving money#

Four tools change something, and three of them move real money. None is a
single call you can stumble into: each is the second half of a pair, and will
only ever submit exactly what the first half prepared.
ToolWhat it does
create_fx_quoteCreates a real, short-lived exchange rate. Moves no money
settle_fx_quoteConverts real money between two of your own accounts
submit_payment_instructionSends a real payment to a beneficiary
submit_fx_payment_instructionSends a real payment, converting as it goes
Each is the second half of a pair: one tool prepares and shows you what
will happen, and the second submits it. The second will only ever send exactly
what was prepared — not a changed version, and not twice, permanently.
Which pair you want depends on the currency:
You want toPair
Pay someone in a currency you holdcreate_payment_instruction → submit_payment_instruction
Pay someone in a currency you do not holdcreate_fx_payment_instruction → submit_fx_payment_instruction
Convert between two of your own accountsget_fx_quote card → create_fx_quote → settle_fx_quote
What the pair does not do is prove a human approved. The key that
authorises the second call reaches the assistant either way — through the card
on clients that render one, and spelled out in the text on clients that do
not — because MCP gives a card no private channel. For converting between your
own accounts the server closes that gap by refusing outright without a card.
For paying a beneficiary it deliberately does not, because the real control
there is the company's approval rules in the Sokin portal plus your client's
own confirmation prompt.
Sending a payment prepares in the conversation and commits from a review card:
Converting currency happens entirely inside one card, because an exchange rate
expires too quickly to survive a back-and-forth in chat:
Submitting is not the same as finished. Both flows hand back a receipt
reference and do the work afterwards. get_instruction_request tells you how
it actually ended.

The tools, one by one#

Each section below gives the tool's name, what it does, what it takes, one
example of what your client sends, and one example of what comes back.
Where a section says "see the Technical Docs", it means the Sokin MCP —
Technical Docs
page, which carries the exact response schemas field by
field, every possible value of every coded field, and the error and pagination
contracts. This page is the guide; that one is the specification.

list_corporates#

Lists the companies your login can act for. Usually the first call of any
session
— nearly every other tool needs a corporate reference, and this is
where one comes from. Read-only.
Takes: nothing.
Request
{"name": "list_corporates", "arguments": {}}
Reply
2 corporates: CORP-8842 — Northwind Trading Ltd (direct assignment); CORP-9110 — Northwind Logistics BV (inherited access).
Reply as data
{
  "data": {
    "items": [
      {"corporateReference": "CORP-8842", "corporateName": "Northwind Trading Ltd", "assignmentType": "direct"},
      {"corporateReference": "CORP-9110", "corporateName": "Northwind Logistics BV", "assignmentType": "inherited"}
    ]
  }
}
assignmentType is direct if you were given access to that company, or
inherited if it comes via a parent.

list_accounts#

All of a company's currency accounts, with balances. Read-only.
TakesRequiredWhat it is
corporate_referenceyesFrom list_corporates
Request
{"name": "list_accounts", "arguments": {"corporate_reference": "CORP-8842"}}
Reply
2 accounts for CORP-8842: CCA-1001 (GBP) — balance 48200.00, of which 47150.00 available; CCA-1002 (USD) — balance 12000.00, available balance not computable.
Reply as data
{
  "message": "Success.",
  "data": [
    {
      "corporateReference": "CORP-8842",
      "corporateCurrencyAccountReference": "CCA-1001",
      "currencyCode": "GBP",
      "balance": "48200.00",
      "availableBalance": "47150.00"
    },
    {
      "corporateReference": "CORP-8842",
      "corporateCurrencyAccountReference": "CCA-1002",
      "currencyCode": "USD",
      "balance": "12000.00",
      "availableBalance": null
    }
  ],
  "pagination": {"nextToken": null, "previousToken": null, "totalItems": 2, "hasMore": false}
}
Balance and available balance are different numbers. Available is the
balance minus whatever is reserved by payments already in flight. It can come
back empty when your login lacks permission to see instructions — the sentence
says so in words rather than showing a zero, and code should expect null.

get_account#

Everything about one account, including the bank details someone would use to
pay money into it. Read-only.
TakesRequiredWhat it is
account_referenceyesAn account reference from list_accounts
Request
{"name": "get_account", "arguments": {"account_reference": "CCA-1001"}}
Reply
Account CCA-1001 (GBP): balance 48200.00, of which 47150.00 available. Local funding: active — ready to receive payments — pay into Northwind Trading Ltd, account 12345678, SortCode 04-00-75, at Modulr FS Limited (London branch), GB. International funding: not yet set up.
Reply as data
{
  "message": "Success.",
  "data": {
    "externalReference": "CCA-1001",
    "currency": "GBP",
    "currentBalance": "48200.00",
    "availableBalance": "47150.00",
    "localAccountStatus": "ACTIVE",
    "internationalAccountStatus": "NOT_PROVISIONED",
    "localPaymentDetails": {
      "accountName": "Northwind Trading Ltd",
      "accountNumber": "12345678",
      "routingCodeType": "SortCode",
      "routingCode": "04-00-75",
      "bankName": "Modulr FS Limited",
      "bankBranch": "London",
      "bankCountry": "GB"
    },
    "internationalPaymentDetails": []
  }
}
An account can have a local route, international routes, or neither set up
yet, so expect either block to be empty. The payment-details objects also
carry IBAN, BIC and address fields where they apply — see the Technical Docs
for the full list.

get_account_ledger#

Transaction history for one account, newest first, a page at a time.
Read-only.
TakesRequiredWhat it is
account_referenceyesThe account to look at
from_datenoOnly entries from this date (YYYY-MM-DD)
to_datenoOnly entries up to this date
limitnoEntries per page (default 25, max 100)
next_tokennoAsk for the next page, using the token from the last one
Request
{
  "name": "get_account_ledger",
  "arguments": {"account_reference": "CCA-1001", "from_date": "2026-08-01", "limit": 25}
}
Reply
3 ledger entries for CCA-1001 (amounts shown as +credit/-debit):
DateTypeAmountCounterpartyDescription
2026-08-14deposit+5000.00Contoso LtdInvoice 4471
2026-08-15withdrawal-1250.00Fabrikam GmbHSupplier payment
2026-08-16FX Trade-800.00GBP to EUR conversion
More results available -- pass next_token='eyJrIjoi...' to see more.
Reply as data
{
  "message": "Success.",
  "data": [
    {
      "amount": "5000.00",
      "direction": "credit",
      "type": "deposit",
      "effectiveDate": "2026-08-14",
      "sourceReference": "Contoso Ltd",
      "beneficiary": null,
      "description": "Invoice 4471",
      "transactionReference": "TXN-77120"
    },
    {
      "amount": "1250.00",
      "direction": "debit",
      "type": "withdrawal",
      "effectiveDate": "2026-08-15",
      "sourceReference": null,
      "beneficiary": "Fabrikam GmbH",
      "description": "Supplier payment",
      "transactionReference": "TXN-77121"
    },
    {
      "amount": "800.00",
      "direction": "debit",
      "type": "FX Trade",
      "effectiveDate": "2026-08-16",
      "sourceReference": null,
      "beneficiary": null,
      "description": "GBP to EUR conversion",
      "transactionReference": "TXN-77122"
    }
  ],
  "pagination": {"nextToken": "eyJrIjoi...", "previousToken": null, "totalItems": 3, "hasMore": true}
}
The amount has no sign — money in and money out both come back positive,
and direction says which it is. The +/- in the table above is added for
readability. The counterparty sits in sourceReference for money in and
beneficiary for money out.
type covers deposits, withdrawals, FX trades and more, and not every value
has a friendly label — see the Technical Docs for the full set before writing
code that switches on it.

list_beneficiaries#

Who a company can pay. Mostly used to check whether a payee already exists,
and to get the reference a payment needs. Read-only, a page at a time.
No tool creates, edits or deletes a beneficiary yet. Every payment has to
name one that already exists in the Sokin platform. get_beneficiary_schema
exists to tell you what a new payee would need, in preparation for that
changing.
TakesRequiredWhat it is
corporate_referenceno, but effectively yesThe company whose payees you want
searchnoMatch against the name. Leave out to list everyone
search_modeno"contains" (default) or "starts_with"
limitnoPer page
next_tokennoToken from the previous page
Request
{
  "name": "list_beneficiaries",
  "arguments": {"corporate_reference": "CORP-8842", "search": "fab", "search_mode": "contains"}
}
Reply
2 beneficiaries:
ReferenceNameTypeCountryCurrencies (rails)Status
BEN-3301Fabrikam GmbHcompanyDEEUR (sepa/swift)active
BEN-3302Jane OkaforindividualGBGBP (faster_payments)active
Reply as data
{
  "data": [
    {
      "externalReference": "BEN-3301",
      "displayName": "Fabrikam GmbH",
      "entityType": "company",
      "countryCode": "DE",
      "destinations": [
        {"currencyCode": "EUR", "paymentRail": "sepa"},
        {"currencyCode": "EUR", "paymentRail": "swift"}
      ],
      "status": "active"
    },
    {
      "externalReference": "BEN-3302",
      "displayName": "Jane Okafor",
      "entityType": "individual",
      "countryCode": "GB",
      "destinations": [{"currencyCode": "GBP", "paymentRail": "faster_payments"}],
      "status": "active"
    }
  ],
  "pagination": {"nextToken": null, "previousToken": null, "totalItems": 2, "hasMore": false}
}
A payee can be reachable in the same currency by more than one route — the
example above can take euros over SEPA or SWIFT, which differ in speed and
cost — so each currency-and-route pair is listed separately rather than
collapsed into one.
This tool also accepts page and offset, purely so it can tell you clearly
that they are not supported. Use limit and next_token.

get_beneficiary#

One payee in full, by reference. Where list_beneficiaries collapses a payee
to its currency-and-route pairs, this returns each destination's actual
account details
— account numbers, routing data, an e-Transfer email, a
crypto wallet address — plus how far each one has been verified. Read-only.
TakesRequiredWhat it is
beneficiary_idyesThe payee's reference from list_beneficiaries
corporate_referenceno, but effectively yesThe company the payee belongs to
Request
{"name": "get_beneficiary", "arguments": {"beneficiary_id": "BEN-3301", "corporate_reference": "CORP-8842"}}
Reply
Fabrikam GmbH -- company, DE, active
CurrencyRailValidationAccount
EURsepamatchedDE89370400440532013000
EURswiftnot_validatedDE89370400440532013000
Created 2026-02-11T09:20:00Z.
Reply as data
{
  "data": {
    "externalReference": "BEN-3301",
    "displayName": "Fabrikam GmbH",
    "entityType": "company",
    "countryCode": "DE",
    "status": "active",
    "isInternal": false,
    "destinations": [
      {
        "currencyCode": "EUR",
        "paymentRail": "sepa",
        "validationStatus": "matched",
        "account_number": "DE89370400440532013000",
        "institution": "Commerzbank AG"
      },
      {
        "currencyCode": "EUR",
        "paymentRail": "swift",
        "validationStatus": "not_validated",
        "account_number": "DE89370400440532013000",
        "institution": "Commerzbank AG"
      }
    ],
    "company": {"registeredName": "Fabrikam GmbH"},
    "address": {"city": "Berlin", "countryCode": "DE"},
    "createdAt": "2026-02-11T09:20:00Z"
  }
}
The Validation column is worth reading before you pay someone.
matched means the account details were checked against the account holder's
name; not_validated means they were not. It is per destination, so the same
payee can be verified on one route and unverified on another.
A payee whose status is deleted gets an explicit closing line saying it
cannot receive payments — do not infer that from the status alone.
One thing this never returns: for an e-Transfer destination without
auto-deposit, the security question comes back but the answer never does.
That answer is what the recipient has to give to claim the money.

get_beneficiary_schema#

What details a new payee needs, for a given payment method, currency and
country — field names, types, which are required, and what values are allowed.
Use it to collect the right information before creating a payee, rather than
guessing and being rejected. Read-only.
Payment method here is a coarser grouping than the payment rails you
see elsewhere. Every rail belongs to exactly one method:
MethodRails
bank_accountfaster_payments, sepa, swift, ach, eft, and the rest
e_transfere_transfer
virtual_accountpix
sokin_internalinternal
cryptobase, tron, ethereum, polygon, solana
TakesRequiredWhat it is
payment_methodyesOne of the five above. crypto is always refused — the upstream endpoint cannot describe crypto payees yet
currency_codeunless sokin_internalCurrency the payee is paid in
country_codeunless sokin_internalCountry of the payee's account
entity_typeunless sokin_internalindividual or company
autodeposit_enrollednoe-Transfer only: "true", "false" or "unknown". Pass "unknown" rather than omitting it when you have not checked — omitting behaves like "true" and leaves the security question optional
corporate_referenceno, but effectively yesThe company the payee will belong to
Request
{
  "name": "get_beneficiary_schema",
  "arguments": {
    "payment_method": "bank_account",
    "currency_code": "GBP",
    "country_code": "GB",
    "entity_type": "company",
    "corporate_reference": "CORP-8842"
  }
}
Reply
Beneficiary schema for bank_account / GBP / GB / company -- 4 fields:
FieldTypeRequiredNotes
displayNamestringyeslength 1-100
bankAccount.accountNumberstringonly for faster_payments
bankAccount.sortCodestringyes
entityTypeenumyesone of: individual, company
Reply as data
{
  "data": {
    "condition": {
      "currencyCode": "GBP",
      "entityType": "company",
      "countryCode": "GB",
      "paymentMethod": "bank_account"
    },
    "fields": [
      {"name": "displayName", "fieldType": "string", "isRequired": true, "min": 1, "max": 100},
      {
        "name": "bankAccount.accountNumber",
        "fieldType": "string",
        "isRequired": true,
        "requiredForPaymentRails": ["faster_payments"]
      },
      {"name": "bankAccount.sortCode", "fieldType": "string", "isRequired": true},
      {
        "name": "entityType",
        "fieldType": "enum",
        "isRequired": true,
        "allowedValues": ["individual", "company"]
      }
    ]
  }
}
Field names are dot-paths into the payee payload, so address.city and
bankAccount.accountNumber tell you where each answer belongs. "Only for
rails" means required just for those routes; "conditional on X" means it
only applies once X has been answered.
A combination the company has no route for is rejected upstream, e.g.
API error (400): No payment rails for GBP+US and bank_account.

list_financial_institutions#

Reference data: banks available when setting up a payee, for the routes that
need one (Canadian EFT, for instance). Read-only, not filterable — the
underlying service takes no options, so neither does this.
Takes: nothing.
Request
{"name": "list_financial_institutions", "arguments": {}}
Reply
2 financial institutions:
IdNameBank Number
1Royal Bank of Canada003
2Toronto-Dominion Bank004
Reply as data
{
  "message": "Success.",
  "data": [
    {"id": 1, "name": "Royal Bank of Canada", "bankNumber": "003"},
    {"id": 2, "name": "Toronto-Dominion Bank", "bankNumber": "004"}
  ]
}
Do not treat this as a complete list of valid banks. It is passed through
from a third party that silently drops records it cannot validate, so a real,
usable bank can be missing from it.

list_financial_institution_branches#

A bank's branches, with routing numbers and addresses, for completing a
payee's details. Read-only, a page at a time.
TakesRequiredWhat it is
financial_institution_idyesThe id from list_financial_institutions
limitnoPer page
next_tokennoToken from the previous page
Request
{"name": "list_financial_institution_branches", "arguments": {"financial_institution_id": 1}}
Reply
1 branch:
IdDescriptionRouting NumberAddressCityStatePostal Code
4412Main Branch000312345200 Bay Street, Suite 400TorontoONM5J2J2
Reply as data
{
  "data": [
    {
      "id": 4412,
      "description": "Main Branch",
      "routingNumber": "000312345",
      "addressLineOne": "200 Bay Street, Suite 400",
      "addressLineTwo": null,
      "city": "Toronto",
      "state": "ON",
      "postalCode": "M5J2J2"
    }
  ],
  "pagination": {"nextToken": null, "previousToken": null, "totalItems": 1, "hasMore": false}
}
An empty result can mean either an unrecognised bank id or a bank with no
branches listed — the service gives no way to tell those apart, so the tool
suggests checking the id against list_financial_institutions.

list_instructions#

Payments and conversions for a company, or for one account. Read-only, a page
at a time.
TakesRequiredWhat it is
corporate_referenceone of these twoList for a whole company
cca_referenceone of these twoList for a single account
completednotrue for finished, false for still in progress
limitnoPer page (default 20, max 100)
next_tokennoToken from the previous page
Give exactly one of the first two — neither or both is an error.
Request
{"name": "list_instructions", "arguments": {"corporate_reference": "CORP-8842", "limit": 20}}
Reply
2 instructions for CORP-8842:
ReferenceAccountTypeAmountCurrencyStatusCreated
INS-5512CCA-1001Payment1250.00GBPProcessed2026-08-15T09:12:44Z
INS-5513CCA-1002FXPayment800.00USDPending Settlement2026-08-16T11:03:02Z
Reply as data
{
  "message": "Success.",
  "data": [
    {
      "instructionReference": "INS-5512",
      "corporateReference": "CORP-8842",
      "ccaReference": "CCA-1001",
      "instructionType": "Payment",
      "amount": "1250.00",
      "currency": "GBP",
      "displayStatus": "Processed",
      "createdAt": "2026-08-15T09:12:44Z",
      "updatedAt": "2026-08-15T09:14:02Z"
    },
    {
      "instructionReference": "INS-5513",
      "corporateReference": "CORP-8842",
      "ccaReference": "CCA-1002",
      "instructionType": "FXPayment",
      "amount": "800.00",
      "currency": "USD",
      "displayStatus": "Pending Settlement",
      "createdAt": "2026-08-16T11:03:02Z",
      "updatedAt": "2026-08-16T11:04:18Z"
    }
  ],
  "pagination": {"nextToken": null, "previousToken": null, "totalItems": 2, "hasMore": false}
}
The account reference matters: a company can hold several accounts in the
same currency, so the currency alone does not tell you which one the money
came from.

get_instruction#

Everything about one payment or conversion — status, amounts, fees, payee.
Read-only.
TakesRequiredWhat it is
instruction_referenceyesThe instruction to look up
Request
{"name": "get_instruction", "arguments": {"instruction_reference": "INS-5513"}}
Reply
Instruction INS-5513 (FXPayment) for corporate CORP-8842, account CCA-1002: 800.00 USD -> 742.10 EUR, status Pending Settlement. Beneficiary: BEN-3301. Sender reference (shown to the recipient): INV-4471. Purpose: SUPPLIER_PAYMENT. Fees: 4.20 FX, 1.50 transaction, 0.00 reseller. Created 2026-08-16T11:03:02Z, updated 2026-08-16T11:04:18Z.
Reply as data
{
  "message": "Success.",
  "data": {
    "externalReference": "INS-5513",
    "displayStatus": "Pending Settlement",
    "instructionType": "FXPayment",
    "corporateReference": "CORP-8842",
    "corporateCurrencyAccount": "CCA-1002",
    "amount": "800.00",
    "destinationAmount": "742.10",
    "sourceCurrency": "USD",
    "destinationCurrency": "EUR",
    "beneficiaryReference": "BEN-3301",
    "senderReference": "INV-4471",
    "paymentPurpose": "SUPPLIER_PAYMENT",
    "sokinFxFee": "4.20",
    "sokinTransactionFee": "1.50",
    "resellerTransactionFee": "0.00",
    "failureReason": null,
    "instructionRequestReference": "IR-Payment-5513",
    "createdAt": "2026-08-16T11:03:02Z",
    "updatedAt": "2026-08-16T11:04:18Z"
  }
}
Parts of the sentence appear only when they apply — a destination amount only
when a conversion happened, a failure reason only when something failed. The
full field list, including a few internal ones this trims away, is in the
Technical Docs.

get_instruction_request#

How a payment or conversion actually turned out. When you submit one, it
is accepted for processing first and worked on afterwards, so being accepted
does not mean it went through. This is the tool that tells you.
Read-only.
TakesRequiredWhat it is
instruction_request_referenceyesThe receipt reference from submitting. Not an instruction reference — those go to get_instruction
Request
{"name": "get_instruction_request", "arguments": {"instruction_request_reference": "IR-Payment-77"}}
Reply
Instruction request IR-Payment-77 was accepted: instruction INS-9 was created. Use get_instruction for its full detail.
Reply as data
{
  "message": "Success.",
  "data": {
    "externalReference": "IR-Payment-77",
    "status": "Accepted",
    "createdInstructionReference": "INS-9",
    "failureReason": null,
    "errorCategory": null
  }
}
Read the status carefully, because the words are misleading:
StatusWhat it actually means
CreatedStill being processed. Not a success
AcceptedSucceeded
RejectedFailed, and the reason is in the result
The other two outcomes read like this:
Instruction request IR-Payment-77 is still being processed -- no outcome yet. Check again shortly.
Instruction request IR-Payment-77 was rejected: Insufficient balance (category: amount). No instruction was created.
If a reference comes back as not found, it is almost always the wrong
reference — commonly an instruction reference used here by mistake. The one
exception is a submission made seconds ago, which can briefly read as missing
while it is being saved; check once more, then stop.

validate_payment_instruction#

Checks a payment without sending it. Runs the same checks as the real
thing — account, payee, balance, fees — and tells you whether it would work.
Nothing is saved and no money moves.
This is the tool to use before preparing a payment, and the one payment tool
that is safe to build on in a client without interactive cards.
TakesRequiredWhat it is
corporate_currency_accountyesThe account to pay from
beneficiary_referenceyesWho to pay, from list_beneficiaries
amountyesPlain decimal, up to 2 places, above zero (e.g. "125.50")
reseller_feenoSame format, zero or more
sender_referencenoText the recipient sees, max 18 characters
payment_purposenoA purpose code, e.g. ACCOUNTS_PAYABLE
amount_is_fees_inclusivenotrue takes fees out of the amount; default adds them on top
Request
{
  "name": "validate_payment_instruction",
  "arguments": {
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "amount": "1250.00",
    "reseller_fee": "1.50",
    "sender_reference": "INV-4471"
  }
}
Reply
Validation passed: this payment would clear the creation checks. Total debit 1256.70 (5.20 Sokin fee, 1.50 reseller fee); beneficiary would receive 1250.00. Nothing was created and no money moved.
Reply as data
{
  "data": {
    "success": true,
    "failureReason": null,
    "errorCategory": null,
    "feeBreakdown": {
      "amount": "1256.70",
      "destinationAmount": "1250.00",
      "sokinFee": "5.20",
      "resellerFee": "1.50",
      "feeRateCardReference": "RC-14"
    }
  }
}
You get the costs even when it fails, which is what makes this useful for
checking affordability:
Validation failed: insufficient available balance on the source account (category: amount). The engine still computed amounts: total debit 1256.70 (5.20 Sokin fee, 1.50 reseller fee). Nothing was created and no money moved.
The amount has to be a plain number like "125.50". Shorthand such as 1e3
is rejected rather than interpreted — for anything to do with money, quietly
guessing what you meant is the worst thing the tool could do.

create_payment_instruction#

Prepares a payment for you to look at. It does not send it. Despite the
name, no payment exists after this and no money has moved.
What it does: re-runs the checks so the card shows Sokin's own figures rather
than the assistant's, then shows you a review card with Approve and
Cancel
. Only your Approve click sends anything.
Needs a client that renders interactive cards. Without one it still
prepares a draft, but no card appears, so nothing can approve it and no
payment can be made. It fails safely — but quietly.
Run validate_payment_instruction first and fix anything it flags. This
tool checks again internally as a guard, and a draft that fails produces no
card at all.
Takes exactly the same arguments as validate_payment_instruction.
Request
{
  "name": "create_payment_instruction",
  "arguments": {
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "amount": "1250.00",
    "reseller_fee": "1.50",
    "sender_reference": "INV-4471"
  }
}
Reply
Payment prepared and validated -- awaiting the user's confirmation in the review widget. Nothing has been submitted; do not report this payment as made, and do not call submit_payment_instruction yourself.
Reply as data
{
  "draft": {
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "amount": "1250.00",
    "reseller_fee": "1.50",
    "sender_reference": "INV-4471",
    "payment_purpose": null,
    "amount_is_fees_inclusive": false
  },
  "currency": "GBP",
  "validation": {
    "success": true,
    "failureReason": null,
    "errorCategory": null,
    "feeBreakdown": {
      "amount": "1256.70",
      "destinationAmount": "1250.00",
      "sokinFee": "5.20",
      "resellerFee": "1.50",
      "feeRateCardReference": "RC-14"
    }
  },
  "idempotencyKey": "a5f1c8e0-7d3b-4f2a-9c61-0b8e4d2f1a77"
}
That key is how the server recognises this exact draft when you approve it.
You never need to handle it yourself.
If you have already sent this exact payment, the result says so and the
card appears with no Approve button — the same payment cannot be sent
twice. To pay the same person the same amount again on purpose, give it a
different sender reference, which makes it a different payment. There is no
way to override this, by design.
A prepared payment you never approve expires after 24 hours, and nothing
happens to it in the meantime.

submit_payment_instruction#

Sends the payment. This moves real money to someone else. It may go out
with no further approval step, and it cannot be cancelled once sent.
Your Approve click on the review card runs this. It is not meant to be
called directly
— it only accepts a payment that was prepared and shown to
you, unchanged, and only once.
TakesRequiredWhat it is
idempotency_keyyesThe key from create_payment_instruction
everything else—Must match the payment you reviewed, exactly
Request
{
  "name": "submit_payment_instruction",
  "arguments": {
    "idempotency_key": "a5f1c8e0-7d3b-4f2a-9c61-0b8e4d2f1a77",
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "amount": "1250.00",
    "reseller_fee": "1.50",
    "sender_reference": "INV-4471"
  }
}
Reply
Payment submitted: instruction request IR-Payment-77 for 1250.00 from CCA-1001 to BEN-3301. This is an instruction-request reference, not a completed payment -- check the outcome via get_instruction_request.
Reply as data
{"data": {"externalReference": "IR-Payment-77"}}
That receipt is not confirmation the payment succeeded. Pass the reference
to get_instruction_request for the real outcome.
What the server refuses, without sending anything:
A payment that was not prepared and shown to you first.
Any change to the amount, payee or reference after you saw it.
The same payment a second time — permanently, not just for a while.
Two approvals racing each other; exactly one can win.
Approving the same payment twice — a double click, a retry — sends nothing
again. The tool looks up what happened the first time and tells you.
If you are building your own client rather than using Claude: the review card
cannot prove who clicked Approve, so your client's own confirmation
prompt for this tool is doing real work.
Treat it as required, not
decorative. The Technical Docs explain the guarantees and their limits
precisely.

create_fx_payment_instruction#

Pays a beneficiary in a currency you do not hold, converting and paying in
one motion. Prepares it for review — it submits nothing, and despite the
name no payment exists after this call.
Use it when the payee wants one currency and you are spending another. For a
payment in a currency you already hold, use create_payment_instruction
instead; for converting between two of your own accounts with no payee, use
the FX quote card.
You do not fetch a rate first. This tool mints its own live quote
internally from the currencies and amount you give it, then runs the same
dry run as a normal payment — so a problem with the payee (missing, cannot
receive that currency, fails verification) is reported here rather than after
someone clicks Approve.
TakesRequiredWhat it is
corporate_currency_accountyesThe account to pay from
beneficiary_referenceyesWho to pay, from list_beneficiaries
buy_currencyyesWhat the beneficiary receives, e.g. "USD"
sell_currencyyesWhat you are spending, e.g. "GBP"
amountyesThe amount of whichever side fixed_side names
fixed_sideno"BUY" or "SELL". Default "SELL"
corporate_referenceno, but effectively yesThe company to quote for. Used only to mint the quote
reseller_feenoPlain decimal, zero or more
sender_referencenoText the recipient sees, max 18 characters
payment_purposenoA purpose code, e.g. ACCOUNTS_PAYABLE
Request
{
  "name": "create_fx_payment_instruction",
  "arguments": {
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "buy_currency": "USD",
    "sell_currency": "GBP",
    "amount": "100.00",
    "fixed_side": "SELL",
    "corporate_reference": "CORP-8842",
    "sender_reference": "INV-4471"
  }
}
Reply, on a client with cards — a not-submitted notice:
FX payment prepared and validated -- awaiting the user's confirmation in the review widget. Nothing has been submitted; do not report this payment as made, and do not call submit_fx_payment_instruction yourself.
Reply, on a client without cards — the figures and both references are
spelled out in the text, because there is no card to carry them:
FX payment prepared and validated -- nothing has been submitted yet. Total debit 100.00 (0.50 Sokin fee, 0.00 reseller fee); beneficiary would receive 125.00 (GBP debited, beneficiary receives USD). idempotency key: 9c21ab4f-... . quote_id: FXQ-1a2b3c... . Read these figures back to the user and get their explicit approval. Only after they approve, call submit_fx_payment_instruction with this idempotency_key, this quote_id, and the same corporate_currency_account, beneficiary_reference, reseller_fee, sender_reference, and payment_purpose you used here -- it does not take buy_currency, sell_currency, amount, fixed_side, or corporate_reference; those only mint the quote. Never submit without that approval, and never tell the user the payment was made until submit_fx_payment_instruction succeeds -- it may still need approval in the Sokin portal afterward.
Reply as data
{
  "draft": {
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "quote_id": "FXQ-1a2b3c",
    "reseller_fee": null,
    "sender_reference": "INV-4471",
    "payment_purpose": null
  },
  "currency": "GBP",
  "buyCurrency": "USD",
  "quoteCreatedAt": "2026-09-16T10:02:00+00:00",
  "quoteExpiresAt": "2026-09-16T10:12:00+00:00",
  "idempotencyKey": "9c21ab4f-7c4e-4a2b-9f31-6d0e2a5b8c14"
}
Note the draft carries a quote_id and no amounts: the amounts come from the
quote, and the currencies and amount you passed exist only to mint it. Pass
that quote_id through unchanged.
The quote can still expire after you approve. The backend re-checks it
when a human approves the instruction in the Sokin portal, which runs at human
pace. If it has lapsed by then, the instruction comes back Rejected with a
reason — not as an error from either tool. quoteExpiresAt is what the card
counts down.

submit_fx_payment_instruction#

Sends the FX payment. This moves real money — it converts and pays a
beneficiary in one motion, and cannot be cancelled once submitted.
Only accepts an idempotency key and quote id that
create_fx_payment_instruction minted, with arguments matching the draft that
was reviewed. On a client with cards the Approve button calls it. On a client
without, calling it directly after the user approves in chat is the intended
path, not a bypass
— that is what the prepare step's text asks you to do.
TakesRequiredWhat it is
idempotency_keyyesThe key from create_fx_payment_instruction
corporate_currency_accountyesMust match the reviewed draft
beneficiary_referenceyesMust match the reviewed draft
quote_idyesFrom the draft's quote_id — the quote the prepare step minted, not one you choose
reseller_feenoMust match the reviewed draft
sender_referencenoMust match the reviewed draft
payment_purposenoMust match the reviewed draft
Request
{
  "name": "submit_fx_payment_instruction",
  "arguments": {
    "idempotency_key": "9c21ab4f-7c4e-4a2b-9f31-6d0e2a5b8c14",
    "corporate_currency_account": "CCA-1001",
    "beneficiary_reference": "BEN-3301",
    "quote_id": "FXQ-1a2b3c",
    "sender_reference": "INV-4471"
  }
}
Reply
FX payment submitted: instruction request IR-FXPayment-77 from CCA-1 to BEN-1. This is an instruction-request reference, not a completed payment -- depending on the corporate's approval rules it may now be awaiting a human approval in the Sokin portal before it is processed. Check the outcome via get_instruction_request.
Reply as data
{"data": {"externalReference": "IR-FXPayment-77"}}
"May be awaiting approval" is deliberately hedged. Whether a submitted
payment needs a further human sign-off depends on the company's own approval
rules in the Sokin platform — a company with none configured has it approved
on creation. Asserting either would be wrong, so get_instruction_request is
how you find out which happened.
Re-submitting the same draft under the same key sends nothing again: the tool
reads the original payment's state and reports it, in
get_instruction_request's shape rather than the single-field one above. Code
parsing this must tolerate both.

get_fx_quote#

Asks what an exchange rate is. Never books anything and never moves money.
What you get back depends on your client:
A client with interactive cards gets a card covering the whole
flow — request, quote, settle — with a countdown. This call alone creates no
quote; the card's Get Quote button does. Do not report a rate from this
call by itself.
A client without gets a real current rate, which is indicative rather
than bookable, plus a link to the Sokin portal to make the trade there.
Why it works that way: a real quote expires in as little as two minutes,
set by whoever priced it. Creating one before a person has seen it would burn
most of that window before anyone could act.
TakesRequiredWhat it is
buy_currencyyesWhat you are buying, e.g. "USD"
sell_currencyyesWhat you are selling, e.g. "GBP"
amountyesThe amount of whichever side fixed_side names
fixed_sideno"BUY" or "SELL". Default "SELL"
corporate_referenceno, but effectively yesWhich company to quote for
corporate_currency_accountnoThe account a later conversion would come from
Request
{
  "name": "get_fx_quote",
  "arguments": {
    "buy_currency": "USD",
    "sell_currency": "GBP",
    "amount": "1000.00",
    "fixed_side": "SELL",
    "corporate_reference": "CORP-8842",
    "corporate_currency_account": "CCA-1001"
  }
}
Reply, with cards — an acknowledgement, not a rate:
Ready to quote GBP -> USD, 1000.00 on the sell side. No quote has been created yet -- the card's Get Quote button mints one.
Reply as data
{
  "buyCurrency": "USD",
  "sellCurrency": "GBP",
  "amount": "1000.00",
  "fixedSide": "SELL",
  "corporateReference": "CORP-8842",
  "corporateCurrencyAccount": "CCA-1001"
}
Reply, without cards — a real rate you cannot book here:
FX quote QT-88213: 1000.00 GBP -> 1187.40 USD at rate 1.18740 (GBPUSD). Fees: 2.50 FX. Valid until 2026-08-27T14:32:10+00:00. Cut-off time: 2026-08-27T16:00:00+00:00. This rate is indicative and short-lived (see the expiry above) -- go to https://portal.uat.sokin.com/v2/transfer/currency-exchange to actually execute this trade; it cannot be settled through this assistant.
Reply as data
{
  "quoteId": "QT-88213",
  "currencyPair": "GBPUSD",
  "fxRate": "1.18740",
  "fixedSide": "SELL",
  "buyAmount": "1187.40",
  "buyCurrency": "USD",
  "sellAmount": "1000.00",
  "sellCurrency": "GBP",
  "fxFees": "2.50",
  "transactionFees": null,
  "currentTime": "2026-08-27T14:30:10+00:00",
  "expiryTime": "2026-08-27T14:32:10+00:00",
  "cutOffTime": "2026-08-27T16:00:00+00:00",
  "holidays": null
}
All times come back as UTC with the offset spelled out, so they cannot be
misread as local time.

create_fx_quote#

Creates a real, short-lived exchange rate and holds the conversion ready.
The FX card's Get Quote button runs this — do not call it directly; start
with get_fx_quote. Only available on a client with interactive cards.
It moves no money, but it is a real action: every call prices a live quote.
How long a quote lasts is decided by whoever priced it, and it varies by
about five times between currency pairs
— some expire in two minutes, some
in around ten. Trust only the expiresAt in the result. Never assume a
duration, and never ask for a quote speculatively or twice for the same
request.
Takes the same currency arguments as get_fx_quote, plus optional
reseller_fee and beneficiary_external_reference. If you leave the account
out, the company's own account in the currency being sold is found
automatically when there is exactly one; with none or several, the card
appears without a Settle option.
Request
{
  "name": "create_fx_quote",
  "arguments": {
    "buy_currency": "USD",
    "sell_currency": "GBP",
    "amount": "1000.00",
    "fixed_side": "SELL",
    "corporate_reference": "CORP-8842",
    "corporate_currency_account": "CCA-1001"
  }
}
Reply
Quote QT-88213 created: 1000.00 GBP -> 1187.40 USD at rate 1.18740. Expires at 2026-08-27T14:34:00+00:00 -- settle it before then, or ask for a fresh quote once it expires.
Reply as data
{
  "quoteId": "QT-88213",
  "idempotencyKey": "7c2e9b41-5a08-4d6f-b3c2-91ef0a4d8b52",
  "currencyPair": "GBP/USD",
  "fxRate": "1.18740",
  "fixedSide": "SELL",
  "buyAmount": "1187.40",
  "buyCurrency": "USD",
  "sellAmount": "1000.00",
  "sellCurrency": "GBP",
  "fxFees": "2.50",
  "createdAt": "2026-08-27T14:32:00+00:00",
  "expiresAt": "2026-08-27T14:34:00+00:00",
  "corporateCurrencyAccount": "CCA-1001",
  "resellerFee": null
}

settle_fx_quote#

Carries out the conversion. This moves real money between two of the
company's own accounts.
Your Settle click on the FX card runs this. Do not call it directly, and never
reuse a key from a different quote — a reused key reports the original
conversion and ignores anything you changed.
Refused outright on a client that does not render interactive cards, before
anything is sent:
Error: this session has not declared MCP UI support, so real-money FX settlement is refused here. Direct the user to the Sokin dashboard to execute this trade instead.
TakesRequiredWhat it is
idempotency_keyyesThe key from create_fx_quote
corporate_currency_accountyesMust match the quote you saw
quote_idyesMust match the quote you saw
reseller_feenoMust match the quote you saw
Request
{
  "name": "settle_fx_quote",
  "arguments": {
    "idempotency_key": "7c2e9b41-5a08-4d6f-b3c2-91ef0a4d8b52",
    "corporate_currency_account": "CCA-1001",
    "quote_id": "QT-88213"
  }
}
Reply
FX conversion submitted: instruction request IR-FX-9911 for account CCA-1001. This is a submission receipt, not confirmation the conversion completed -- check get_instruction_request for its actual outcome.
Reply as data
{"data": {"externalReference": "IR-FX-9911", "status": "Created"}}
Remember that Created means still processing. Use
get_instruction_request for the outcome — it is a read, and it answers
however long ago the conversion happened.
Things that stop a conversion, none of which send anything:
Anything different from the quote you reviewed.
A quote that has expired — you get the real reason, and can ask for a fresh
one.
A second attempt while the first is still in flight.
If a conversion's outcome is genuinely unknown — a timeout, say — the tool
says exactly that rather than guessing, and tells you to check before
retrying. Submitting a conversion is also not the same as it being approved:
whether it needs a further sign-off depends on the company's own approval
rules in the Sokin platform.

visualize#

Draws a diagram or renders rich text inside the chat. Needs a client with
interactive cards. Calls no Sokin service.
Most read tools have no card of their own, so this is how a result gets a
picture: the assistant reads the data, writes a diagram from it, and passes it
here.
TakesRequiredWhat it is
markdownyesMarkdown to render. Code blocks tagged mermaid become diagrams
titlenoThe card's heading
Request
{
  "name": "visualize",
  "arguments": {
    "title": "Balances by currency",
    "markdown": "```mermaid\npie title Balances\n  \"GBP\" : 48200\n  \"USD\" : 12000\n```"
  }
}
Reply
The card itself, rendered in the chat. There is no summary sentence — the text
half of the reply is the markdown you passed, echoed back unchanged.
Reply as data
{"title": "Balances by currency", "markdown": "```mermaid\npie title Balances\n  \"GBP\" : 48200\n  \"USD\" : 12000\n```"}
The card is about 600 pixels wide with no height limit, so top-to-bottom
diagrams work better than left-to-right, and about 10 to 15 boxes is the
practical maximum before it gets cramped.

get_documentation_links#

Hands back the web addresses of Sokin's own documentation, so an assistant can
read the real contract instead of guessing. Links only — never the content.
The answer is specific to the environment you are connected to, so a UAT
session gets UAT's documentation.
TakesRequiredWhat it is
topicno"b2b_api", "mcp_server", or "all". Default "all"
Request
{"name": "get_documentation_links", "arguments": {"topic": "all"}}
Reply
Sokin documentation for the MCP server at https://mcp.uat.sokin.com.
DocumentationURLWhat's there
Sokin B2B API referencehttps://docs.sokin.com/llms.txtThe Sokin B2B REST API this MCP server calls: every endpoint, authentication, API versions, and request/response schemas
Sokin MCP server reference(none available)No published reference yet -- every tool on this server is self-describing, so read the tool list and tool descriptions you already have from this connection
Reply as data
{
  "mcpServerUrl": "https://mcp.uat.sokin.com",
  "documentation": [
    {
      "topic": "b2b_api",
      "title": "Sokin B2B API reference",
      "url": "https://docs.sokin.com/llms.txt",
      "alternateUrl": "https://docs.sokin.com",
      "summary": "The Sokin B2B REST API this MCP server calls: every endpoint, authentication, API versions, and request/response schemas"
    },
    {
      "topic": "mcp_server",
      "title": "Sokin MCP server reference",
      "url": null,
      "alternateUrl": null,
      "summary": "No published reference yet -- every tool on this server is self-describing, so read the tool list and tool descriptions you already have from this connection"
    }
  ]
}
A topic with nothing published yet still gets a row, with the reason in place
of a link, rather than being left out.
Why the MCP row is empty in the example above, when this guide names a
Technical Docs page: that page exists but is not published at a public URL
yet, so the deployment has no address to hand out. The tool reports the gap
instead of returning a link that would need a login. Once the docs are
published and the deployment is configured with their URL, this row carries it
with no change to the tool.

play_cheetah_dash#

An endless-runner game, rendered in the chat. Takes nothing and calls no Sokin
service. Needs a client with interactive cards.
Request
{"name": "play_cheetah_dash", "arguments": {}}
Reply
Cheetah Dash is ready -- use Space or tap to jump, again mid-air to double jump.
There is no Reply as data below, because this is the one tool that answers
with just a line of text and no structured data at all.

Starter project ideas#

All built on read-only tools — nothing moves money. Say the prompt in plain
English and let the client pick the tools.
IdeaToolsPrompt to try
Multi-currency balance dashboardlist_corporates, list_accounts"Build a dashboard of all my Sokin balances by currency, with a bar chart of the biggest five."
FX quote checkerget_fx_quote"Make a page where I enter an amount and from/to currency and it shows the current Sokin FX quote."
Transaction history explorerget_account_ledger"Build a screen to pick an account and list its recent transactions, newest first, with a date filter."
Beneficiary directorylist_beneficiaries"Create a searchable directory of my saved beneficiaries with currency and country."
Payment pre-flight checkervalidate_payment_instruction"Let me paste payment details and flag any problems, without submitting anything."
The last one is the stretch, and it is still safe:
validate_payment_instruction saves nothing and moves no money.

Going deeper#

Exact response schemas, field by field, every possible value of every
coded field, and the error and pagination contracts: Sokin MCP —
Technical Docs
.
The Sokin B2B REST API underneath: https://docs.sokin.com, or
https://docs.sokin.com/llms.txt for the machine-readable index.
From inside a chat, ask for the documentation links and
get_documentation_links will return the ones for the environment you are
actually on.
Modified at 2026-09-16 11:21:06
Previous
Sokin MCP - Setup and Usage Guide
Next
Sokin MCP - Technical Docs
Built with