Managing Contacts
After creating a contact (see Making Your First Payment), you can list and update their details as information changes.
List contacts
Retrieve a paginated list of contacts for an originator.
curl "https://staging.api.now.luqra.com/v1/contacts?originatorId=ORIGINATOR_ID" \
-H "Authorization: Bearer luqra-now.org.test.YOUR_API_KEY"
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
originatorId |
string (UUID) | required | The originator whose contacts to list |
search |
string | — | Filter by name, email, or company name (case-insensitive) |
limit |
integer | 20 |
Number of contacts per page (1–100) |
cursor |
string | — | Pagination cursor from a previous response's meta.pagination.nextCursor |
Response
{
"data": [
{
"contactId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"entityType": "INDIVIDUAL",
"companyName": null,
"firstName": "Jane",
"lastName": "Smith",
"email": "ja*******h@example.com",
"phoneNumber": null,
"legalAddress": {
"addressLine1": "123 Main St",
"addressLine2": null,
"city": "Springfield",
"state": "IL",
"postalCode": "62701",
"countryCode": "US"
},
"bankAccount": null,
"createdAt": "2026-03-15T14:30:00.000Z"
}
],
"meta": {
"timestamp": "2026-05-19T10:00:00.000Z",
"pagination": {
"limit": 20,
"nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTAzLTE1VDE0OjMwOjAwLjAwMFoiLCJpZCI6IjZiYTdiODEwLTlkYWQtMTFkMS04MGI0LTAwYzA0ZmQ0MzBjOCJ9"
}
}
}
When nextCursor is null, there are no more pages. To fetch the next page, pass the cursor value as the cursor query parameter:
curl "https://staging.api.now.luqra.com/v1/contacts?originatorId=ORIGINATOR_ID&cursor=NEXT_CURSOR&limit=20" \
-H "Authorization: Bearer luqra-now.org.test.YOUR_API_KEY"
Sensitive fields (email, phone number, bank account numbers, and routing numbers) are masked in all responses.
Update a contact
Send a PATCH request with only the fields you want to change. At least one field must be provided.
curl -X PATCH "https://staging.api.now.luqra.com/v1/contacts/CONTACT_ID" \
-H "Authorization: Bearer luqra-now.org.test.YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.smith@newdomain.com",
"phoneNumber": "+14155551234"
}'
Updatable fields
| Field | Type | Description |
|---|---|---|
entityType |
string | INDIVIDUAL or BUSINESS |
companyName |
string or null |
Required for BUSINESS, nullable for INDIVIDUAL. Max 100 characters. |
firstName |
string | 1-50 characters. Letters, spaces, hyphens, apostrophes, and periods only. Optional for BUSINESS, which is identified by companyName. Cannot be cleared -- null is rejected. |
lastName |
string | 1-50 characters. Letters, spaces, hyphens, apostrophes, and periods only. Optional for BUSINESS, which is identified by companyName. Cannot be cleared -- null is rejected. |
email |
string | Valid email address. Max 254 characters. |
phoneNumber |
string or null |
US phone number. Accepts various formats (e.g., +19497037012, (949) 703-7012, 949-703-7012). Stored and returned in E.164 format. |
legalAddress |
object | Full address object (see below) |
bankAccount |
object | Full bank account object (see below) |
Changing entityType
BUSINESS contacts are identified by companyName and may have no first or last name, so switching one to INDIVIDUAL takes more than the entityType field alone:
- Send
companyName: null. AnINDIVIDUALcontact cannot carry a company name, and the stored one is kept unless you clear it in the same request. - Send
firstNameandlastNameunless the contact already has both stored. AnINDIVIDUALcontact must have a person name.
curl -X PATCH "https://staging.api.now.luqra.com/v1/contacts/CONTACT_ID" \
-H "Authorization: Bearer luqra-now.org.test.YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entityType": "INDIVIDUAL",
"companyName": null,
"firstName": "Jane",
"lastName": "Smith"
}'
Switching the other way, to BUSINESS, requires companyName in the same request unless the contact already has one stored. First and last name are left as they are.
Sending an unchanged entityType never triggers these checks, so a contact that predates this rule can still be updated field by field.
Nested objects
When updating legalAddress or bankAccount, provide the full object -- partial nested updates are not supported.
legalAddress:
{
"legalAddress": {
"addressLine1": "456 Oak Ave",
"addressLine2": "Suite 200",
"city": "Springfield",
"state": "IL",
"postalCode": "62702",
"countryCode": "US"
}
}
| Field | Required | Description |
|---|---|---|
addressLine1 |
Yes | Must contain at least one letter and one digit. Max 100 characters. |
addressLine2 |
No | Optional. Max 100 characters. |
city |
Yes | Must contain at least one letter. Max 50 characters. |
state |
Yes | US state or territory code (e.g., IL, CA, PR). |
postalCode |
Yes | 5-digit US ZIP code (no ZIP+4). |
countryCode |
Yes | Currently only US is accepted. |
bankAccount:
{
"bankAccount": {
"subType": "CHECKING",
"achRoutingNumber": "021000021",
"achAccountNumber": "987654321"
}
}
| Field | Required | Description |
|---|---|---|
subType |
Yes | CHECKING or SAVINGS |
achRoutingNumber |
Yes | 9-digit ABA routing number with valid checksum |
achAccountNumber |
Yes | 5-17 alphanumeric characters |
swiftCode |
No | SWIFT/BIC code |
Response
The response returns the full contact with updated values. Sensitive fields (bank account numbers, routing numbers, email, and phone number) are masked in the response.
{
"data": {
"contactId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"entityType": "INDIVIDUAL",
"companyName": null,
"firstName": "Jane",
"lastName": "Smith",
"email": "ja*******h@newdomain.com",
"phoneNumber": "********1234",
"legalAddress": {
"addressLine1": "123 Main St",
"addressLine2": null,
"city": "Springfield",
"state": "IL",
"postalCode": "62701",
"countryCode": "US"
},
"bankAccount": {
"bankName": null,
"swiftCode": null,
"subType": "CHECKING",
"achRoutingNumber": "*****0021",
"achAccountNumber": "*****6789"
},
"updatedAt": "2026-03-15T14:30:00.000Z"
},
"meta": { "timestamp": "2026-03-15T14:30:00.000Z" }
}
Error responses
| Code | Reason |
|---|---|
400 |
Invalid request body or no fields provided |
Switching to INDIVIDUAL without clearing companyName -- Company name is not allowed for individual entity type |
|
Switching a BUSINESS contact with no first or last name to INDIVIDUAL without supplying both -- First name and last name are required for individual entity type |
|
Switching to BUSINESS without a companyName -- Company name is required for business entity type |
|
401 |
Missing or invalid API key |
404 |
Contact not found or does not belong to your organization |
409 |
Conflicting update (e.g., concurrent modification) |