Vopify MCP Integration
Vopify exposes a Model Context Protocol (MCP) endpoint that allows AI assistants and automation tools to run payee verifications, retrieve verification history, and check account status on behalf of authenticated users. Compatible with Claude, ChatGPT, n8n, and any MCP-compatible tool.
Endpoint: https://vopify.io/mcp
Transport: Streamable HTTP (MCP spec 2025-06-18)
Auth: OAuth 2.1 — Bearer tokenAuthentication
Vopify's MCP uses OAuth 2.1 with bearer tokens issued by Vopify's sign-in service. When connecting a new tool, you will be redirected to log in with your Vopify account credentials. The resulting bearer token is scoped to your account — all verifications consume credits from your balance.
Token audience: authenticatedAvailable tools
Vopify exposes 3 tools via MCP. All tools return the standard MCP CallToolResult shape — a content array where content[0].text contains the JSON-stringified payload, and a structuredContent object containing the same data parsed.
typescript{ content: [{ type: "text", text: string }], // JSON-stringified payload structuredContent?: object, // same payload as parsed object isError?: boolean // true for tool-level failures where set }
verify_payee
Runs a real-time Verification of Payee check against the specified payment network and account details. Attempts to deduct 1 credit only when a verification result is returned (errorCategory: "verification_complete"). Credits are not charged for input errors, account issues, bank limitations, or temporary failures.
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | string | ✅ Always | Payment network: EUR, GBP, VND, INR, IDR, KRW, CNY; unsupported values receive INVALID_FIELD |
| name | string | ✅ Always | Account holder name — 1–200 characters |
| holderType | enum | ✅ Except CNY | individual or business — ignored for CNY |
| iban | string | ✅ EUR, optional GBP | Required for EUR. For GBP use either iban or sortCode + accountNumber |
| sortCode | string | GBP only | 6-digit UK sort code — dashes stripped automatically |
| accountNumber | string | GBP (if no iban), INR, IDR, KRW, VND | Bank account number |
| ifscCode | string | INR only | Indian IFSC code e.g. HDFC0001234 |
| bankCode | string | IDR, KRW, VND | Bank identifier code |
| alipayId | string | CNY only | Alipay registered phone number or email address |
Network quick-reference
| Network | network | holderType | iban | sortCode + accountNumber | ifscCode | bankCode | alipayId |
|---|---|---|---|---|---|---|---|
| SEPA / EUR | EUR | ✅ | ✅ | — | — | — | — |
| UK CoP / GBP | GBP | ✅ | IBAN or | sort code + account | — | — | — |
| Vietnam / VND | VND | ✅ | — | ✅ | — | ✅ | — |
| India / INR | INR | ✅ | — | ✅ | ✅ | — | — |
| Indonesia / IDR | IDR | ✅ | — | ✅ | — | ✅ | — |
| South Korea / KRW | KRW | ✅ | — | ✅ | — | ✅ | — |
| China / Alipay | CNY | ❌ | — | — | — | — | ✅ |
Result — structuredContent
typescript{ errorCategory: "input_validation" | "account_action_required" | "bank_limitation" | "verification_complete" | "transient_error", verificationOutcome: "match" | "partial_match" | "no_match" | null, errorCode: string | null, resolvedName: string | null, // partial_match only — always null for CNY message: string, // user-facing, safe to display directly creditCharged: boolean, // true when a completed check deducted a credit creditsRemaining: number | null, network: string | null, // unsupported input can be returned unchanged referenceId?: string // only on unexpected TEMPORARILY_UNAVAILABLE failures }
| Field | Description |
|---|---|
| errorCategory | Classification of the result. verification_complete — result returned, creditCharged indicates whether a credit was deducted. input_validation — invalid inputs, no credit charged. account_action_required — your account needs attention (session expired, not enough credits, or suspended), no credit charged. bank_limitation — verification is restricted or unavailable, no credit charged. transient_error — temporary failure, no credit charged. |
| verificationOutcome | The match result. Only populated when errorCategory is verification_complete. |
| resolvedName | The correct name held by the bank. Populated on partial_match only. Always null for CNY. |
| message | User-facing description of the result — safe to display directly in your UI or workflow. |
| creditCharged | true only when a completed check actually deducted a credit. |
| creditsRemaining | Updated balance when available; null if it could not be read. |
| referenceId | Present only for an unexpected temporary failure; include it when contacting support. |
match or no_match only — partial_match is not supported on this network. resolvedName will always be null for CNY.Example responses
json{ "errorCategory": "verification_complete", "verificationOutcome": "match", "errorCode": null, "resolvedName": null, "message": "Verification complete — the name matches the account holder. ✓ One credit was used.", "creditCharged": true, "creditsRemaining": 147, "network": "EUR" }
Error codes
The following codes are returned as structured results, not isError: true. A completed verification has errorCode: null.
| errorCode | errorCategory | Meaning |
|---|---|---|
| MISSING_REQUIRED_FIELD | input_validation | A required network-specific field or name is missing. |
| INVALID_FIELD | input_validation | Unsupported network, invalid field length or format. |
| MISSING_FIELDS | input_validation | Required account details are missing during server validation. |
| INVALID_NAME_FORMAT | input_validation | Account holder name format is invalid. |
| INVALID_IBAN | input_validation | IBAN format or country is invalid. |
| INVALID_IBAN_CHECKSUM | input_validation | IBAN check digits do not match. |
| SWIFT_NOT_IFSC | input_validation | A SWIFT/BIC code was entered instead of an IFSC. |
| INVALID_IFSC_FORMAT | input_validation | IFSC format is invalid. |
| IFSC_UNKNOWN_BANK | input_validation | IFSC does not match a recognized bank. |
| INVALID_ACCOUNT_FORMAT | input_validation | Account number or routing format is invalid. |
| INVALID_BANK_CODE | input_validation | Bank code is missing, invalid or unrecognized. |
| INVALID_UPI_FORMAT | input_validation | UPI ID format is invalid. |
| INVALID_ALIPAY_FORMAT | input_validation | Alipay ID is not a valid phone number or email. |
| BANK_REJECTED_ACCOUNT | input_validation | Account number was rejected. |
| BANK_REJECTED_ACCOUNT_IFSC | input_validation | Account number and IFSC combination was rejected. |
| BANK_REJECTED_IFSC | input_validation | IFSC was rejected. |
| UPI_NOT_RECOGNIZED | input_validation | UPI ID was not recognized. |
| ACCOUNT_NOT_EXIST | input_validation | Account number does not exist at the selected bank. |
| INVALID_ACCOUNT_BANK_PAIR | input_validation | Account number does not match the selected bank. |
| ALIPAY_COMBO_INVALID | input_validation | Alipay ID and name combination could not be verified. |
| SESSION_EXPIRED | account_action_required | Reconnect Vopify in your assistant. No credit was used. |
| INSUFFICIENT_CREDITS | account_action_required | Add credits at vopify.io/billing. No credit was used. |
| ACCOUNT_SUSPENDED | account_action_required | Contact operations@vopify.io. No credit was used. |
| CANNOT_VERIFY | bank_limitation | Account cannot be verified on this network. |
| ACCOUNT_CLOSED | bank_limitation | Account has been closed. |
| NETWORK_NOT_ENABLED | bank_limitation | Verification is not enabled on this network. |
| COULD_NOT_CHECK | transient_error | Check could not be completed right now. |
| PROVIDER_ERROR | transient_error | Temporary verification service failure. |
| NETWORK_ERROR | transient_error | Temporary connection failure. |
| AUTH_FAILURE | transient_error | Temporary internal service error — retry later. This is not a problem with your session; no need to reconnect. |
| TEMPORARILY_UNAVAILABLE | transient_error | Unexpected failure; use referenceId when contacting support. |
For an invalid network the message is “Please choose a supported network: EUR, GBP, INR, IDR, KRW, VND or CNY. No credit was used.” For insufficient credits it is “Your Vopify account doesn't have enough credits for this check. Add credits at vopify.io/billing and try again. No credit was used.” Other results include a user-facing message.
list_verifications
Returns the authenticated user's recent verification history, most recent first. Results are scoped to the authenticated account — you cannot retrieve another user's history.
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| limit | integer | ❌ | 20 | 1–100 | Number of recent records to return |
content[0].text contains the JSON-stringified array directly — not wrapped in an object. structuredContent contains { rows: [...] }. Always read from structuredContent in n8n and programmatic clients to avoid double-parsing.typescript{ rows: Array<{ created_at: string | null, // ISO 8601 timestamp network: string | null, // payment network iban_suffix: string | null, // last 4 characters of account identifier provided_name: string | null, result_status: "FULL_MATCH" | "PARTIAL_MATCH" | "NO_MATCH" | "UNAVAILABLE", suggested_name: string | null }> }
json{ "rows": [ { "created_at": "2025-07-10T14:32:00Z", "network": "EUR", "iban_suffix": "4300", "provided_name": "Sample Payee", "result_status": "FULL_MATCH", "suggested_name": null }, { "created_at": "2025-07-10T13:11:00Z", "network": "EUR", "iban_suffix": "7890", "provided_name": "Sample-Payee", "result_status": "PARTIAL_MATCH", "suggested_name": "Sample Payee" } ] }
Error responses (isError: true)
- Expired session — reconnect Vopify in your assistant
- History query failure — “Your verification history couldn't be loaded right now. Please try again in a moment.” Internal details are logged, not returned.
account_status
Returns the authenticated user's credit balance and active plan. Takes no parameters — pass an empty object {}.
Parameters: None.
typescript{ email: string | null, credits: number, plan: "Starter" | "Growth" | "Scale" | "Pay-as-you-go" | "Subscription", subscription: null | { status: "active" | "trialing" | "past_due", renewsAt: string | null, cancelAtPeriodEnd: boolean } }
The most recent live subscription is preferred, otherwise the most recent eligible subscription. A recognized subscription maps to Starter, Growth or Scale; an unrecognized subscription is labeled Subscription. Without an active, trialing or past-due subscription, the plan is Pay-as-you-go and subscription is null.
json{ "email": "sample@example.com", "credits": 1348, "plan": "Growth", "subscription": { "status": "active", "renewsAt": "2026-11-03T00:00:00Z", "cancelAtPeriodEnd": false } }
Error responses (isError: true)
- Expired session — reconnect Vopify in your assistant
- Account or subscription query failure — “Your account status couldn't be loaded right now. Please try again in a moment.”
Connecting Vopify MCP
- In Claude, open Settings → Connectors → Add custom connector
- Enter Vopify and the server URL
https://vopify.io/mcp. Vopify is not in the connector directory yet. - Click Connect and log in with your Vopify account credentials
- Once connected, Claude can call all three tools on your behalf
- Try: "Verify that IBAN NL91ABNA0417164300 belongs to Sample Payee — individual account, SEPA network"
Error handling
verify_payee returns structured results for invalid input, expired sessions, suspended accounts, insufficient credits, bank limitations and temporary errors; it does not set isError: true in its handler. Use errorCategory and errorCode for these outcomes. list_verifications and account_status return isError: true with safe plain text on expired sessions or query failures. Protocol, authentication or schema rejections can also occur before a tool handler returns a structured result. Always check isError when present, then inspect structuredContent.
javascriptconst result = await mcpClient.callTool("verify_payee", params); if (result.isError) { // Tool-level or protocol failure — re-authenticate or retry console.error(result.content[0].text); return; } const data = result.structuredContent; switch (data.errorCategory) { case "verification_complete": // 1 credit charged — process the result console.log(data.verificationOutcome); // "match" | "partial_match" | "no_match" console.log(data.resolvedName); // suggested name for partial_match break; case "input_validation": // No credit charged — fix the inputs console.log(data.message); break; case "bank_limitation": // No credit charged — bank doesn't support verification console.log(data.message); break; case "transient_error": // No credit charged — retry after a delay break; case "account_action_required": // No credit charged — reconnect, top up credits, or contact support console.log(data.message); break; }
Credits and billing
- 1 credit is deducted on a completed
verify_payeecheck; checkcreditChargedfor confirmation - While a check runs, 1 credit is held on your balance. It is kept only if the check completes and returned automatically otherwise. Held-and-returned credits don't appear in your transaction history.
- No credit is charged for
input_validation,account_action_required,bank_limitation, ortransient_erroroutcomes creditCharged: truein the response confirms a credit was consumedcreditsRemainingshows your balance when available; it can benullif it could not be read- If your balance is too low,
verify_payeereturnserrorCategory: "account_action_required"with an insufficient credits message — no credit consumed - Check your balance anytime using
account_statusor at vopify.io/billing
Changelog
October 3, 2026. Changed:
- Expired session, suspended account, insufficient credits — Before:
errorCategory: "input_validation"with codesSESSION_EXPIRED,ACCOUNT_SUSPENDED,INSUFFICIENT_CREDITS; structured result,isErrornot set. Now:errorCategory: "account_action_required", same codes, new reconnect / support / billing messages; structured result,isErrornot set. - Unsupported network value — Before: rejected by the connector's input schema before reaching Vopify; no
errorCategoryorerrorCode; may previously have returned a tool error (isError: true). Now:errorCategory: "input_validation",errorCode: "INVALID_FIELD"with the supported-network message; structured result,isErrornot set. - Missing required field — Before: generic validation error. Now:
errorCategory: "input_validation",errorCode: "MISSING_REQUIRED_FIELD"naming the field; structured result,isErrornot set. - Unexpected failures — Before: the raw error was surfaced as a tool error (
isError: true) with no category or code. Now:errorCategory: "transient_error",errorCode: "TEMPORARILY_UNAVAILABLE"with areferenceIdfor support; structured result,isErrornot set. - Check order — Now: input validation, then session, then suspension, then credits, so input problems are reported before account problems.
account_status— Before: no plan field. Now: returnsplanand asubscriptionobject.list_verifications— Before: no network field. Now: each item includesnetwork.
Need help?
For integration support, email operations@vopify.io with subject line MCP Integration Support. Include your client platform (n8n, Claude, ChatGPT, or custom), the tool you're calling, the parameters you're sending (redact any real IBANs or account numbers), and the full response you're receiving.