Vortex
    • Overview
    • Quick Start With The SDK
    • Authentication And Partner Keys
    • Ramp Lifecycle
    • Ephemeral Key Custody
    • Quotes And Pricing
    • Webhooks
    • Widget Integration
    • BRL / KYC notes
    • Sandbox
    • Production Checklist
    • AI Agent Integration
    • Quotes
      • Get existing quote
        GET
      • Create a new quote
        POST
      • Create a quote for the best network
        POST
    • Vortex Widget
      • Widget parameters
      • Generating widget URL (for existing quote)
        POST
      • Generating widget URL (for existing quote)
        POST
    • Ramp
      • Get ramp status
        GET
      • Get ramp history for wallet address
        GET
      • Register new ramp process
        POST
      • Update ramp process
        POST
      • Start ramp process
        POST
      • Get ramp error logs
        GET
    • Account Management
      • Brazil
        • Brazilian KYC Process Overview
        • Get status of the last ramp event for a user
        • Start KYC level 2 process for a user
      • Europe
        • Coming soon...
      • Get user's remaining transaction limits
        GET
      • Get KYC document upload URLs
        POST
      • Get user information
        GET
      • Create user or retry KYC
        POST
      • Submit KYC level 1 data
        POST
      • Get selfie liveness URL
        GET
      • Get user's KYC status
        GET
      • Validate Pix key
        GET
    • Webhooks
      • Register Webhook
      • Delete Webhook
    • Public Key
      • Overview
      • Public Key
    • Reference Data
      • Supported Payment Methods
      • Supported Cryptocurrencies
      • Supported Countries
      • Supported Fiat Currencies
    • Schemas
      • Schemas
      • StartKYC2Response
      • GetKycStatusResponse
      • ValidatePixKeyResponse
      • GetUserRemainingLimitResponse
      • TriggerOfframpRequest
      • TriggerOfframpResponse
      • BrlaAddress
      • TaxIdType
      • CreateSubaccountRequest
      • CreateSubaccountResponse
      • KYCDocType
      • KYCDataUploadFileFiles
      • StartKYC2Request
      • GetUserResponse
      • StartRampRequest
      • RampDirection
      • GetWidgetUrlLocked
      • CountryCode
      • PaymentMethod
      • SimpleStatus
      • FiatToken
      • OnChainToken
      • GetWidgetUrlRefresh
      • CreateBestQuoteRequest
      • GetRampHistoryTransaction
      • GetRampHistoryResponse
      • BrlaErrorResponse
      • RegisterRampRequest
      • AccountMeta
      • Networks
      • PaymentData
      • RampProcess
      • RampPhase
      • DestinationType
      • UnsignedTx
      • CleanupPhase
      • CreateQuoteRequest
      • QuoteResponse
      • RampCurrency
      • UpdateRampRequest
      • PresignedTx
      • ErrorResponse
      • RampErrorLog
      • GetRampErrorLogsResponse
      • BrlaValidatePixKeyResponse
      • BrlaGetSelfieLivenessUrlResponse
      • AveniaDocumentType
      • AveniaKYCDataUploadRequest
      • DocumentUploadEntry
      • AveniaKYCDataUploadResponse
      • KycLevel1Payload
      • KycLevel1Response

    AI Agent Integration

    This page is written so that an AI coding agent (or a human engineer using one) can build a production-quality Vortex integration in any language or stack. It also explains how to keep these docs themselves useful when retrieved into a coding agent's context.

    A. Using These Docs With An AI Agent

    When you point an AI coding agent at Vortex:

    • Anchor the agent on this section first. Pages 1–11 describe the protocol and contracts; this page describes what a correct client must do.
    • Treat the OpenAPI file as the source of truth for shapes, and these Markdown pages as the source of truth for behavior, ordering, custody, signing, and timing. Both are required; neither is sufficient alone.
    • Pin versions. Record the commit hash of these docs and the version of @vortexfi/sdk you are mirroring. The SDK's behavior is the reference implementation; if your integration disagrees with it, the SDK wins.
    • Never let the agent invent endpoints, fields, status values, or fee categories. If something is not in the OpenAPI file or these pages, the agent should stop and ask.
    • Force the agent to validate every signed payload before signing: chainId, verifyingContract, to, value, data, and ramp/phase identifiers must match what your application requested for the current rampId.

    B. Picking An Integration Path

    Your runtimePath
    Node.js (server-side, trusted)Use @vortexfi/sdk.
    Python (server-side, trusted)Use vortex-sdk-python.
    Browser, mobile, WebViewUse the Vortex Widget.
    Anything else (Go, Rust, Elixir, Java, Ruby, PHP, .NET, Deno, edge runtimes, …)Reimplement the SDK behavior against the raw API as described in Section D below.

    Do not call the raw ramp API from a browser. Browsers cannot safely hold sk_* keys or ephemeral secrets. Use the Widget or proxy through a trusted backend.

    C. Python (vortex-sdk-python)

    vortex-sdk-python is a process-bridge wrapper around the native Node.js SDK. It spawns the Node SDK and exposes a Python-friendly surface, so the behavior, custody model, and supported flows match @vortexfi/sdk exactly.

    pip install vortex-sdk-python
    
    from vortex_sdk import VortexSdk, RampDirection, FiatToken, EvmToken, Networks
    
    sdk = VortexSdk(
        api_base_url="https://api.vortexfinance.co",
        public_key="pk_live_...",
        secret_key="sk_live_...",
        store_ephemeral_keys=True,
    )
    
    quote = sdk.create_quote(
        ramp_type=RampDirection.BUY,
        from_="pix",
        to=Networks.Polygon,
        input_amount="150",
        input_currency=FiatToken.BRL,
        output_currency=EvmToken.USDC,
    )
    
    ramp = sdk.register_ramp(quote, destination_address="0x...", tax_id="12345678900")
    print(ramp.deposit_qr_code)
    sdk.start_ramp(ramp.id)
    

    Operational notes specific to the Python wrapper:

    • A Node.js runtime must be available on the host. The wrapper manages its own Node process.
    • Ephemeral key storage rules from the Node SDK apply: by default ephemerals_{rampId}.json is written unencrypted in the working directory.
    • The Node SDK opens three persistent WebSocket connections on init; reuse one VortexSdk(...) instance for the lifetime of your service.

    Refer to the PyPI page for the latest version, function names, and breaking-change notes: https://pypi.org/project/vortex-sdk-python.

    D. Reimplementing The SDK In Any Language

    If your stack is neither Node nor Python, build a thin client that mirrors what @vortexfi/sdk does. The contract has six parts; implement them in this order.

    D.1 Configuration And Auth

    Your client needs:

    • apiBaseUrl — https://api.vortexfinance.co (prod) or https://api-sandbox.vortexfinance.co (sandbox).
    • publicKey — pk_live_* / pk_test_*. Sent in request bodies as apiKey for attribution.
    • secretKey — sk_live_* / sk_test_*. Sent as X-API-Key header. Server-side only.

    Reject startup if a sk_live_* key is detected in a browser-shaped runtime.

    D.2 Quote

    POST /v1/quotes
    

    Request body: see 6. Quotes And Pricing. Treat monetary fields as strings end-to-end; never parse them into floats. Store id, expiresAt, fee, and the resolved route. Surface expiry to the caller as a domain error.

    D.3 Register

    POST /v1/ramp/register
    X-API-Key: sk_*
    

    Before calling register, generate per-chain ephemeral accounts for the chains involved in the route:

    • EVM legs → a fresh secp256k1 keypair.
    • Substrate legs (Pendulum, AssetHub, Moonbeam, Hydration) → fresh sr25519 keypairs.
    • Stellar legs → a fresh Ed25519 keypair.

    Send only the public addresses in the register request. Persist the secret keys to your secure store, keyed by the not-yet-issued ramp; once the response returns a rampId, rekey the store entry. Never log the secrets.

    The response contains:

    • rampId
    • current ramp state and phase
    • unsignedTxs — an ordered list of transactions to sign

    Each unsigned transaction declares its network, signer address, transaction format (evm-transaction, evm-typed-data, substrate-extrinsic, stellar-transaction), and the payload bytes or fields to sign.

    D.4 Sign And Update

    For each unsigned transaction:

    1. Route by signer.
      • If tx.signer equals an ephemeral address you control → sign with the matching ephemeral key.
      • If tx.signer equals the user's wallet address → return the payload to the user's wallet for signing (EIP-712 typed data, EVM transaction, or Substrate extrinsic). Never sign user-controlled transactions on the server.
    2. Validate the payload before signing.
      • chainId matches the network the SDK config declared.
      • to / verifyingContract is one of the Vortex-published contracts for that network.
      • value, asset, and amount match the current ramp quote.
      • For EVM ramps, ephemeral signers must use 5 consecutive nonces starting from the current account nonce (NUMBER_OF_PRESIGNED_TXS = 5).
      • Bump EVM gas: multiply both maxPriorityFeePerGas and maxFeePerGas returned by the node by 3× before signing.
    3. Submit the result back to Vortex.
    POST /v1/ramp/update
    X-API-Key: sk_*
    

    Body includes the rampId, the transaction reference, and either the signed payload or the broadcast transaction hash. The exact shape is defined in the OpenAPI file; do not guess fields.

    D.5 Fiat Payment And Start

    • BRL buy: the register response contains depositQrCode (PIX). Show it; wait for the user to pay. Then call POST /v1/ramp/start.
    • BRL sell: the user signs the user-owned transaction(s) and you submit them via update. Then call start. Vortex pays out to the user's PIX key.
    POST /v1/ramp/start
    X-API-Key: sk_*
    

    D.6 Track

    • Register a webhook via POST /v1/webhook against quoteId or sessionId. Verify every delivery using RSA-PSS / SHA-256 against GET /v1/public-key. See 7. Webhooks.
    • Poll GET /v1/ramp/{id} for live user-facing UI.
    • Pull GET /v1/ramp/{id}/errors for support.

    E. Mandatory Client Responsibilities

    These are not optional. The SDK handles them for you; a custom client must implement them explicitly.

    1. Ephemeral key custody. Generate fresh per-ramp keypairs. Store them encrypted, keyed by rampId. Keep them until the ramp is COMPLETE or FAILED and any recovery window has passed. Never transmit secrets to Vortex, support, logs, or analytics. See 5. Ephemeral Key Custody.
    2. Payload validation before signing. Every field that affects funds movement must match what your application requested.
    3. Idempotency. Wrap register, update, and start with idempotency keys at your layer. Retries must not produce duplicate ramps.
    4. Retries with backoff. The Vortex SDK does not retry, time out, or poll on your behalf. Add a retry policy with jittered exponential backoff for transient failures (5xx, network) and surface 4xx errors as terminal.
    5. Quote-expiry handling. Catch expiry errors on register. Create a fresh quote and re-prompt the user.
    6. Webhook signature verification. Reject any webhook that fails RSA-PSS verification or whose X-Vortex-Timestamp is outside an acceptable window (300s is a reasonable default).
    7. HTTPS-only webhook endpoints. Plain HTTP is rejected.
    8. Persistent state. Persist quoteId, rampId, sessionId, partner order ID, user identifier, webhook IDs, and a reference to the ephemeral-key backup. Without these you cannot support users or reconcile.
    9. Type safety on amounts. All monetary fields are decimal strings. Do not parse to float; use a decimal library (e.g. BigDecimal, decimal.Decimal).
    10. WebSocket lifecycle (if applicable). If you mirror the SDK's chain-side behavior, expect to maintain Pendulum, Moonbeam, and Hydration WebSocket connections. Reuse one client per process; do not open a new connection per request.
    11. Sandbox / production isolation. Use pk_test_* / sk_test_* against api-sandbox.vortexfinance.co. Never mix test keys with the live base URL or vice versa.

    F. Things The SDK Does Not Do (And Neither Should A Custom Client Pretend To)

    • It does not retry failed HTTP requests.
    • It does not poll ramp status; you must poll or use webhooks.
    • It does not encrypt ephemeral backups at rest.
    • It does not delete ephemeral backups after success.
    • It does not drive BRLA KYC; the user must be onboarded through the Vortex app or Widget before a BRL ramp.
    • It does not support EUR onramp today (throws "Euro onramp handler not implemented yet").

    Mirror those gaps deliberately. If your integration adds behavior the SDK lacks (encryption at rest, backup rotation, idempotency keys, retries), document it for your operators.

    G. Minimum Viable Integration Checklist

    Before going live without the SDK:

    • Server-side only; sk_* keys never reach a browser.
    • Per-ramp ephemeral keypairs generated and stored encrypted.
    • Every signed payload validated before signing.
    • EVM nonce + gas rules implemented (5 consecutive nonces, 3× gas bump).
    • User-owned transactions routed to the user's wallet, not signed on the server.
    • POST /v1/ramp/update called with the exact transaction reference returned by register.
    • Webhook signature + timestamp verification implemented and tested.
    • Quote expiry produces a clean retry path.
    • Sandbox tested for: successful buy, successful sell, expired quote, failed payment, webhook retry, dropped ephemeral signer.
    • Production runbook covers ramp recovery using persisted rampId and ephemeral backup.

    See also 11. Production Checklist.

    Modified at 2026-05-18 18:56:31
    Previous
    Production Checklist
    Next
    Get existing quote
    Built with