Inyo

Transaction

The Transaction endpoint is the culmination of the remittance flow. It links together the sender, recipient, funding source, recipient account, and quote to execute a cross-border payment.


Creating a Transaction

Endpoint: POST /organizations/{tenant}/fx/transactions
Authentication: Agent-level (x-api-key + x-agent-id + x-agent-api-key)

Request Body

FieldTypeRequiredDescription
senderIdstring (UUID)YesThe participant ID of the sender (from POST /people)
recipientIdstring (UUID)YesThe participant ID of the recipient (from POST /people)
fundingAccountIdstring (UUID)YesThe sender's funding source (from POST /fundingAccounts)
recipientAccountIdstring (UUID)YesThe recipient's bank account (from POST /recipientAccounts/gateway)
quoteIdstring (UUID)YesThe locked FX quote (from POST /payout/quotes)
externalIdstring (UUID)NoYour internal reference ID for idempotency and reconciliation
additionalDataobjectYesCountry-specific data and device fingerprint (see below). Pass {} if no additional data is required for the corridor.
additionalData.fingerprintstringYesThe requestId returned by the device fingerprint library
additionalData.visitorstringYesThe visitorId returned by the device fingerprint library
deviceDataobjectNoDevice fingerprinting data for fraud prevention
deviceData.userIpAddressstringRecommendedThe end user's IP address

Device Fingerprint (Required)

Every transaction requires a device fingerprint for fraud prevention. You must integrate a device fingerprint library into your client application. Inyo will provide the API keys for the fingerprint service during onboarding.

Before submitting a transaction, call the fingerprint library on the client side to obtain a requestId and visitorId. Pass these values in the additionalData object:

  • additionalData.fingerprint — the requestId from the fingerprint library
  • additionalData.visitor — the visitorId from the fingerprint library

These fields are required on every transaction. Requests without valid fingerprint data will be rejected.

Sample Request

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": "422a55b2-78c3-4509-8654-16e7375d3e40",
  "recipientId": "4b9dcb4e-2e2a-4e96-b2a9-fcd868b2f4ed",
  "fundingAccountId": "3fe5f23f-65d3-41b6-b34c-33db3c4d8ef9",
  "recipientAccountId": "67203d69-dc48-41d4-b2ac-52682d39b032",
  "quoteId": "30bf05d2-b416-4e71-b8e8-1ef158a2b414",
  "additionalData": {
    "fingerprint": "1727364523875.mchLfB",
    "visitor": "jkS9xp4FHlqOSfGR"
  },
  "deviceData": {
    "userIpAddress": "200.123.131.112"
  }
}'

Sample Response (HTTP 202)

{
  "id": "9035ee18-052b-4176-a940-ccfe599a1829",
  "sender": {
    "id": "ce06773d-6472-4c93-bdf5-8eb68ab01c7f",
    "type": "PERSON",
    "name": "Rob Dalas",
    "phoneNumber": "+1 123 456435"
  },
  "recipient": {
    "id": "156675d5-1d1b-4b4d-997e-5c15ae129b82",
    "type": "PERSON",
    "name": "Bob Danilo",
    "phoneNumber": "+55 71 91234-5678"
  },
  "tenantId": "master",
  "externalId": null,
  "agentId": "41f55211-1eea-4747-9a03-68e99f07ede5",
  "createdAt": "2025-05-29T17:26:27.264312",
  "anchorCurrencyAmount": {
    "amount": "102.53",
    "currency": "USD"
  },
  "complianceStatus": "Approved",
  "payoutStatus": "Pending",
  "status": {
    "id": "0097c1fb-56ac-4314-afa1-eaf00e712d5b",
    "transactionId": "e58796a9-e809-4503-8ce3-2c96c0a0e170",
    "complianceStatus": "Approved",
    "payoutStatus": "Pending",
    "messages": [
      {
        "id": "7122d9ab-2e60-41a4-94aa-e4231b1ca4f7",
        "message": "STANDARD - PAYMENT_RECEIVED",
        "createdBy": "system",
        "createdAt": "2025-11-21T11:48:10.268817",
        "type": "SystemUpdate"
      }
    ],
    "createdAt": "2025-11-21T14:48:05.891186"
  },
  "quoteId": "af2d55d8-1d40-426a-8d4a-7454ccdcbe8a",
  "fundingAccountId": "61bc14a1-b3a2-40b4-b395-0496e4f554a1",
  "recipientAccountId": "4fbc57a6-f673-44ba-88aa-c6e71eb9181b",
  "exchangeRate": "5.571062480000000",
  "totalAmount": {
    "amount": "102.53",
    "currency": "USD"
  },
  "receivingAmount": {
    "amount": "571.20",
    "currency": "BRL"
  },
  "fee": {
    "amount": "1.54",
    "currency": "USD"
  },
  "conversionAmount": {
    "amount": "102.53",
    "currency": "USD"
  },
  "originExchangeRate": {
    "fromCurrency": "USD",
    "toCurrency": "USD",
    "rate": "1.000000000000000"
  },
  "destinationExchangeRate": {
    "fromCurrency": "USD",
    "toCurrency": "BRL",
    "rate": "5.571062480000000"
  },
  "type": "FX",
  "senderId": "ce06773d-6472-4c93-bdf5-8eb68ab01c7f",
  "recipientId": "156675d5-1d1b-4b4d-997e-5c15ae129b82"
}

Response Fields

FieldDescription
idUnique transaction ID
complianceStatusCurrent compliance screening result
payoutStatusCurrent payout delivery status
status.messagesAudit trail of status transitions with timestamps
exchangeRateThe applied FX rate
totalAmountTotal amount charged to the sender (in source currency)
receivingAmountAmount to be received by the beneficiary (in destination currency)
feeTransaction fee in source currency
conversionAmountAmount that was converted (source currency)
originExchangeRateExchange rate from source currency to anchor currency
destinationExchangeRateExchange rate from anchor currency to destination currency
typeTransaction type: FX, TOP_UP, or BILLPAY

Transaction Status Lifecycle

Every transaction has two independent status dimensions:

Compliance Status

StatusDescription
ApprovedPassed all compliance checks — transaction can proceed
HoldFlagged for manual review by the compliance team
RejectedFailed compliance screening — transaction is blocked

Payout Status

StatusDescription
PendingTransaction accepted, awaiting processing
PaidFunds successfully delivered to the recipient
CancelledTransaction was cancelled (by user request or compliance rejection)
FailedTransaction was failed (by payment gateway)
RefundedTransaction was refunded

Compliance Status Transitions

                    ┌──────────┐
              ┌─────│          │─────┐
              │     └────┬─────┘     │
              │          │           │
              │          │           │
              │     ┌────▼─────┐     │  
              │┌────│   Hold   │────┐│
              ││    └──────────┘    ││
              ││                    ││
          ┌────▼──────┐       ┌─────▼▼────┐
          │ Rejected  │       │ Approved  │
          │(Cancelled)│       └───────────┘
          └───────────┘

Querying Transactions

Get Transaction by ID

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID \
  --header "x-api-key: $API_KEY"

List Transactions with Filters

curl --request GET \
  --url "https://{FQDN}/organizations/$TENANT/fx/transactions?page=0&size=20&type=FX&complianceStatus=Approved" \
  --header "x-api-key: $API_KEY"

Query Parameters:

ParameterTypeDescription
pageintegerPage number (0-indexed)
sizeintegerResults per page
typestringFilter by type: FX, TOP_UP, BILLPAY
complianceStatusstringFilter by compliance status
payoutStatusstringFilter by payout status
senderNamestringFilter by sender name
receiverNamestringFilter by receiver name
fromstringStart date filter
tostringEnd date filter

Get Transaction Status History

Returns the full audit trail of status changes for a transaction.

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID/status \
  --header "x-api-key: $API_KEY"

Sample Response:

[
  {
    "id": "2f6b3f12-a63f-43f7-9bb4-4e98dfc75fe5",
    "complianceStatus": "Approved",
    "payoutStatus": "Pending",
    "transactionId": "46b4c393-3768-4ba4-b6d2-a6398e17dd78",
    "tenantId": "master",
    "externalId": "GMT000648512199",
    "createdAt": "2024-01-03T12:54:09.455",
    "messages": [
      {
        "id": "0fbbddb8-283d-466d-b2e6-42dcbb3e67de",
        "message": "STANDARD - PAYMENT_RECEIVED",
        "createdBy": "system",
        "createdAt": "2025-11-19T13:29:52.221882",
        "type": "SystemUpdate"
      }
    ]
  }
]

Cancelling a Transaction

Cancel a transaction that has not yet been paid out. Cancellation is allowed when the payout status is Pending.

Endpoint: PUT /organizations/{tenant}/fx/transactions/{transactionId}/status/cancel
Authentication: Tenant-level (x-api-key)

curl --request PUT \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID/status/cancel \
  --header "x-api-key: $API_KEY"

Responses:

StatusDescription
204Transaction successfully cancelled
400Cannot cancel — transaction is in a non-cancellable state
404Transaction not found

⚠️ Once a transaction reaches Paid status, it cannot be cancelled — use the refund endpoint instead.


Refunding a Transaction

Refund a transaction that has already been paid.

Endpoint: PUT /organizations/{tenant}/fx/transactions/{transactionId}/status/refund
Authentication: Tenant-level (x-api-key)

curl --request PUT \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID/status/refund \
  --header "x-api-key: $API_KEY"

Responses:

StatusDescription
204Refund initiated
400Cannot refund — transaction is not in Paid payout status
404Transaction not found

Updating Transaction Metadata

Attach arbitrary key-value data to a transaction for your internal tracking.

Endpoint: PUT /organizations/{tenant}/fx/transactions/{transactionId}/metadata
Authentication: Tenant-level (x-api-key)

curl --request PUT \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID/metadata \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --data '{
  "internalRef": "INV-2025-001",
  "department": "treasury"
}'

Transaction Limits

Before executing a transaction, verify the sender has not exceeded their limits.

Endpoint: GET /organizations/{tenant}/fx/participants/{participantId}/limits
Authentication: Agent-level

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

Sample Response:

{
  "oneDayLimit": {
    "limit": { "amount": "2999.00", "currency": "USD" },
    "used": { "amount": "0.00", "currency": "USD" },
    "available": { "amount": "2999.00", "currency": "USD" }
  },
  "thirtyDaysLimit": {
    "limit": { "amount": "6000.00", "currency": "USD" },
    "used": { "amount": "2959.99", "currency": "USD" },
    "available": { "amount": "3040.01", "currency": "USD" }
  },
  "oneHundredAndEightyDaysLimit": {
    "limit": { "amount": "9999.00", "currency": "USD" },
    "used": { "amount": "5000.00", "currency": "USD" },
    "available": { "amount": "4999.00", "currency": "USD" }
  },
  "complianceLevel": {
    "level": "LEVEL_1",
    "requiredFields": ["birthDate", "lastName", "name", "occupation", "phoneNumber", "residentialAddress"]
  }
}

Receipts (Regulatory Requirement)

As an agent of a licensed Money Service Business, you are legally required to issue a receipt to the sender immediately after transaction submission. The transaction response includes a receipt object with mandatory regulatory disclosures that must be displayed verbatim to the end user.

The receipt must include:

  1. Exchange rate — the locked-in rate from the quote
  2. Fees — total fees charged to the customer
  3. Total amount — full amount paid by the sender
  4. Receive amount — exact amount to be received by the beneficiary
  5. Regulatory disclosures — dynamic legal text specific to the corridor (e.g., right to refund, cancellation policy)

⚠️ You must not alter the financial data or regulatory text returned by the API. Display it as-is.


Error Responses

HTTP StatusErrorCause
400Bad requestMissing required fields, invalid data format, or expired quote
403ForbiddenAgent not approved, or sender doesn't meet compliance requirements
422Unprocessable entityBusiness rule violation (e.g., limit exceeded, invalid corridor)

Additional Endpoints

OperationMethodEndpoint
Create transactionPOST/organizations/{tenant}/fx/transactions
Get transactionGET/organizations/{tenant}/fx/transactions/{transactionId}
List transactionsGET/organizations/{tenant}/fx/transactions
Get status historyGET/organizations/{tenant}/fx/transactions/{transactionId}/status
Cancel transactionPUT/organizations/{tenant}/fx/transactions/{transactionId}/status/cancel
Refund transactionPUT/organizations/{tenant}/fx/transactions/{transactionId}/status/refund
Update metadataPUT/organizations/{tenant}/fx/transactions/{transactionId}/metadata
Check limitsGET/organizations/{tenant}/fx/participants/{participantId}/limits
Get transaction schemaGET/organizations/{tenant}/fx/transactions/schema?countryCode={iso2}

Interactive API Documentation