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. An INDIVIDUAL contact cannot carry a company name, and the stored one is kept unless you clear it in the same request.
  • Send firstName and lastName unless the contact already has both stored. An INDIVIDUAL contact 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)