Inyo

Getting Started

This guide walks you through sending your first cross-border transaction on the Inyo sandbox. By the end, you'll have a working remittance from a US sender to an international recipient.


Prerequisites

Before you begin, ensure you have:

  • Sandbox credentials provided by Inyo during onboarding:
    • tenant — Your organization identifier
    • x-api-key — Primary API key (Tenant-level)
    • x-agent-id — Your agent UUID
    • x-agent-api-key — Agent-level API key
  • Node.js v18+ (if running the sample project)
  • A REST client (cURL, Postman, or similar)

📬 Don't have credentials yet? Get in touch with our sales team to request sandbox access.


Sandbox Environment

ResourceURL
Core API (sandbox)https://{FQDN}
OpenAPI docshttps://dev-api.inyoglobal.com/sandbox/
Developer portalhttps://dev.inyoglobal.com

Quick Start: Your First Transaction

This walkthrough covers the minimum steps to execute a USD → BRL remittance in the sandbox.

Step 1: Create the Sender

Register the person who will send money. This triggers KYC/AML screening.

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/people \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --data '{
  "firstName": "John",
  "lastName": "Doe",
  "email": "[email protected]",
  "birthDate": "1990-01-15",
  "phoneNumber": "+15551234567",
  "gender": "Male",
  "address": {
    "countryCode": "US",
    "stateCode": "CA",
    "city": "San Francisco",
    "line1": "123 Market St",
    "zipcode": "94105"
  },
  "documents": [
    {
      "type": "SSN",
      "document": "123456789",
      "countryCode": "US"
    }
  ]
}'

⚠️ Save the returned id — this is the senderId used throughout the transaction lifecycle.

Step 2: Verify Compliance Level

Confirm the sender has reached at least Level 1 before proceeding.

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/participants/$SENDER_ID/complianceLevels \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY"

If the response shows LEVEL_0, the sender is missing required fields. Check the nextLevel.requiredFields array to see what's needed.

Step 3: Get Available Destinations

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/payout/us/destinations \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY"

This returns the list of countries your tenant is enabled to send to, along with their currencies.

Step 4: Lock in an FX Quote

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/quotes \
  --header 'Content-Type: application/json' \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "fromCurrency": "USD",
  "toCurrency": "BRL",
  "amount": 100.00
}'

⚠️ Save the quoteId from the response. Quotes expire in ~2 minutes.

Step 5: Create the Recipient

First, fetch the required schema for the destination country:

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/payout/recipients/schema/br \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY"

Then create the recipient using the schema-required fields:

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/people \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --data '{
  "firstName": "Maria",
  "lastName": "Silva",
  "phoneNumber": "+5511999998888",
  "documents": [
    {
      "type": "CPF",
      "document": "12345678901",
      "countryCode": "BR"
    }
  ]
}'

⚠️ Save the returned id — this is the recipientId.

Fetch the account schema, then link the bank account:

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/participants/$RECIPIENT_ID/recipientAccounts/gateway \
  --header 'Content-Type: application/json' \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "externalId": "recipient-acct-001",
  "asset": "BRL",
  "payoutMethod": {
    "type": "BANK_DEPOSIT",
    "countryCode": "BR",
    "bankCode": "001",
    "routingNumber": "0001",
    "accountNumber": "123456",
    "accountType": "CHECKING"
  }
}'

⚠️ Save the returned id — this is the recipientAccountId.

Step 7: Register the Sender's Funding Source

You can fund transactions with either a debit card or an ACH bank account (via Plaid).

Option A: Debit Card

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/participants/$SENDER_ID/fundingAccounts \
  --header 'Content-Type: application/json' \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "externalId": "funding-001",
  "asset": "USD",
  "nickname": "My Debit Card",
  "paymentMethod": {
    "type": "CARD",
    "ipAddress": "127.0.0.1",
    "token": "tok_sandbox_test_token",
    "bin": "541333",
    "schemeId": "MASTERCARD",
    "lastFourDigits": "3303",
    "billingAddress": {
      "countryCode": "US",
      "stateCode": "CA",
      "city": "San Francisco",
      "line1": "123 Market St",
      "zipcode": "94105"
    }
  }
}'

Option B: ACH (via Plaid)

First, create a Plaid link token, then complete the Plaid Link flow on the client to get the accountCheckId and accountCheckToken. See Sender Funding Account for the full ACH flow.

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/participants/$SENDER_ID/fundingAccounts \
  --header 'Content-Type: application/json' \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "externalId": "funding-002",
  "asset": "USD",
  "nickname": "My Checking Account",
  "paymentMethod": {
    "type": "ACH",
    "countryCode": "US",
    "accountCheckId": "PLAID_ACCOUNT_ID",
    "accountCheckToken": "PLAID_PUBLIC_TOKEN"
  }
}'

Save the returned id — this is the fundingAccountId.

Step 8: Execute the Transaction

Link all the IDs together and submit:

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions \
  --header 'Content-Type: application/json' \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "senderId": "'$SENDER_ID'",
  "recipientId": "'$RECIPIENT_ID'",
  "fundingAccountId": "'$FUNDING_ACCOUNT_ID'",
  "recipientAccountId": "'$RECIPIENT_ACCOUNT_ID'",
  "quoteId": "'$QUOTE_ID'",
  "additionalData": {},
  "deviceData": {
    "userIpAddress": "127.0.0.1"
  }
}'

A successful response returns HTTP 202 with the full transaction object, including complianceStatus, payoutStatus, exchange rate details, and the receipt object containing legally required disclosures.


What's Next?


Common Issues

SymptomCauseFix
401 UnauthorizedInvalid API keysVerify x-api-key, x-agent-id, and x-agent-api-key in your .env
403 ForbiddenAgent not approved, or sender below compliance Level 1Check agent approval status; verify sender's compliance level
400 Missing fieldsIncomplete sender/recipient profileCheck schema endpoints for required fields per country
422 UnprocessableQuote expired, limit exceeded, or invalid referencesRefresh the quote; check limits via GET /fx/participants/{id}/limits
429 Too Many RequestsRate limit exceededImplement caching for destinations, banks, and schemas (24h TTL)

Feedback & Support

We're continuously improving these docs. For feedback, questions, or technical issues: