Sender
The Sender is the participant who initiates and pays for a transaction. Every sender must pass through KYC (Know Your Customer) screening, and their transaction limits are determined by their compliance level.
Initial Compliance Setup
At the beginning of your integration, the Inyo compliance team works with your organization to define a custom compliance framework tailored to your product and customer profile. This framework determines:
- Compliance levels β tiers that define how much a customer can send within set timeframes (24h, 30d, 180d)
- Validation rules β the required data and documents for each level (e.g., name, SSN, proof of income)
- Risk controls β thresholds that trigger enhanced due diligence
This configuration is unique per tenant and directly impacts how participants are verified and which operations they can perform.
Creating a Sender
Endpoint: POST /organizations/{tenant}/people
Authentication: Tenant-level (x-api-key)
No fields are technically required to create a person β but to use them as a sender, they must reach at least Compliance Level 1, which typically requires first name, last name, address, and phone number.
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",
"externalId": "your-internal-id-001",
"address": {
"countryCode": "US",
"stateCode": "CA",
"city": "San Francisco",
"line1": "123 Market St",
"zipcode": "94105"
},
"documents": [
{
"type": "SSN",
"document": "123456789",
"countryCode": "US"
}
],
"occupation": "Software Engineer"
}'
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
firstName | string | For Level 1 | First name |
lastName | string | For Level 1 | Last name |
phoneNumber | string | For Level 1 | Phone with country code (e.g., +15551234567) |
email | string | For US persons | Email address |
gender | string | For US persons | Male, Female, or Other |
birthDate | string | For US persons | Format: yyyy-MM-dd |
externalId | string | No | Your internal reference ID |
address | object | For Level 1 | Residential address |
address.countryCode | string | Yes (in address) | ISO 3166-1 alpha-2 |
address.stateCode | string | For US | US state code (e.g., CA) |
address.city | string | Yes (in address) | City name |
address.line1 | string | Yes (in address) | Street address |
address.line2 | string | No | Additional address info |
address.zipcode | string | Yes (in address) | Postal code |
documents | array | For Level 2+ | Identity documents |
documents[].type | string | Yes (in doc) | SSN, ITIN (US), CPF (BR), etc. |
documents[].document | string | Yes (in doc) | Document number |
documents[].countryCode | string | Yes (in doc) | Issuing country |
occupation | string | For Level 2 | Person's occupation |
employerName | string | No | Employer name |
Sample Response
{
"id": "48066496-9445-41b7-acbe-85e069a77cb7",
"firstName": "John",
"lastName": "Doe",
"mainAddressId": "9c2ea7e5-51a2-4ea1-83cf-8948754486f8",
"phoneNumber": "+15551234567",
"email": "[email protected]",
"gender": "Male",
"birthDate": "1990-01-15",
"externalId": "your-internal-id-001",
"updatedAt": "2025-01-15T12:00:00",
"documents": [],
"occupation": "Software Engineer",
"documentId": null,
"sourceOfFundsId": null,
"employerName": null,
"employerAddressId": null
}
Save the returned
idβ this is thesenderIdused in all subsequent API calls.
Behavior notes:
- Idempotent on
externalIdβ if a person with the sameexternalIdalready exists in your tenant,POST /peoplereturns the existing person instead of creating a duplicate. - Senders must be 18+ β
birthDateis rejected if the person would be under 18. - Documents are append-only β updating a person's documents inserts new records and retires the old ones, preserving the compliance audit trail.
Updating a Sender
Endpoint: PATCH /organizations/{tenant}/people/{personId}
Authentication: Tenant-level
Only fields included in the request body are updated; omitted fields remain unchanged.
curl --request PATCH \
--url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID \
--header 'Content-Type: application/json' \
--header "x-api-key: $API_KEY" \
--data '{
"occupation": "Consultant",
"documents": [
{
"type": "SSN",
"document": "987654321",
"countryCode": "US"
}
]
}'
Address Verification
Use the address check endpoint to pre-validate an address before creating or updating a sender. It applies the same country-aware validation rules (including per-country zipcode formats) as the real save endpoints, so a passing check here means the address will be accepted on POST /people.
curl --request GET \
--url "https://{FQDN}/organizations/$TENANT/addresses/check?countryCode=US&stateCode=CA&city=San+Francisco&line1=123+Market+St&zipcode=94105" \
--header "x-api-key: $API_KEY"
Query parameters: line1, city, stateCode, and countryCode are required; zipcode is validated against the destination country's format rules.
| Response Code | Meaning |
|---|---|
200 | Address is valid β the response includes { "valid": true, "normalized": { ... } } |
422 | Validation failed β VALIDATION_ERROR with a per-field breakdown |
Creating Business Senders (KYB)
For B2B use cases, you can create a company as a sender:
Endpoint: POST /organizations/{tenant}/companies
Authentication: Tenant-level
Companies follow a similar compliance level system but with different required fields (business registration, EIN, etc.). Contact your Inyo account manager for your tenant-specific KYB configuration.
Compliance Levels
| Level | Typical Required Fields | Description |
|---|---|---|
| Level 0 | (none) | Cannot transact |
| Level 1 | firstName, lastName, address, phoneNumber | Basic KYC |
| Level 2 | SSN, occupation, document ID | Enhanced KYC |
| Level 3 | Proof of source of funds | Full KYC |
These are customizable per tenant. See Trust Level Limits for details.
Best Practices
- Progressive onboarding β Collect only Level 1 fields at signup. Prompt for more data when the user needs higher limits.
- Pre-validate addresses β Use the address check endpoint before creating the sender to avoid holds.
- Sync compliance state β After profile updates, re-check the compliance level to see if it has upgraded.
- Handle restricted users β If a sender is
Restricted, checkGET /participants/{id}/complianceLevelsto understand why and what action is needed.
Related Pages
- Trust Level Limits β Check and upgrade compliance levels
- Uploading Documents β Submit ID and source-of-funds documents
- Test Data β Sandbox testing scenarios for compliance flows
All Endpoints
| Operation | Method | Endpoint |
|---|---|---|
| Create person | POST | /organizations/{tenant}/people |
| Update person | PATCH | /organizations/{tenant}/people/{personId} |
| Get person | GET | /organizations/{tenant}/people/{personId} |
| Get person with details | GET | /organizations/{tenant}/people/{personId}/details |
| Update address | PUT | /organizations/{tenant}/people/{personId}/address |
| Update employer address | PUT | /organizations/{tenant}/people/{personId}/employerAddress |
| Update place of birth | PUT | /organizations/{tenant}/people/{personId}/placeOfBirth |
| Check address | GET | /organizations/{tenant}/addresses/check |
