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 identifierx-api-key— Primary API key (Tenant-level)x-agent-id— Your agent UUIDx-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
| Resource | URL |
|---|---|
| Core API (sandbox) | https://{FQDN} |
| OpenAPI docs | https://dev-api.inyoglobal.com/sandbox/ |
| Developer portal | https://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 thesenderIdused 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
quoteIdfrom 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 therecipientId.
Step 6: Link the Recipient's Bank Account
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 therecipientAccountId.
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 thefundingAccountId.
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?
- Set up webhooks to receive real-time transaction status updates
- Review the transaction lifecycle to understand status transitions
- Explore compliance levels to build progressive KYC flows
- Check test data for sandbox testing scenarios
Common Issues
| Symptom | Cause | Fix |
|---|---|---|
401 Unauthorized | Invalid API keys | Verify x-api-key, x-agent-id, and x-agent-api-key in your .env |
403 Forbidden | Agent not approved, or sender below compliance Level 1 | Check agent approval status; verify sender's compliance level |
400 Missing fields | Incomplete sender/recipient profile | Check schema endpoints for required fields per country |
422 Unprocessable | Quote expired, limit exceeded, or invalid references | Refresh the quote; check limits via GET /fx/participants/{id}/limits |
429 Too Many Requests | Rate limit exceeded | Implement caching for destinations, banks, and schemas (24h TTL) |
Feedback & Support
We're continuously improving these docs. For feedback, questions, or technical issues:
- 📧 Get in touch with our sales team
- 📖 Interactive API reference
- 💻 Sample project on GitHub
