Skip to content

Import a contact

Almost every integration starts here. This recipe creates one Individual contact with primary phone, email, and address rows, then re-fetches it through the dashboard endpoint to verify the round-trip.

  • contacts:create
  • contacts:view (for the round-trip read)
Terminal window
curl -sS -X POST \
-H "X-Api-Key: $AURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contactType": "Individual",
"firstName": "Jane",
"lastName": "Donor",
"phones": [{ "phoneNumber": "+1-415-555-0142", "phoneType": "Mobile", "isPrimary": true }],
"emails": [{ "emailAddress": "[email protected]", "emailType": "Personal", "isPrimary": true }],
"addresses": [{
"addressType": "Home",
"isPrimary": true,
"line1": "1 Market St",
"city": "San Francisco",
"stateProvince": "CA",
"postalCode": "94105",
"country": "US"
}]
}' \
"https://api.auradonors.com/api/tenants/$TENANT_ID/contacts"

A successful response is 201 Created:

{
"id": 1834,
"contactType": "Individual",
"firstName": "Jane",
"lastName": "Donor",
"phones": [{ "id": 5012, "phoneNumber": "+1-415-555-0142", "isPrimary": true, ... }],
"emails": [{ "id": 4318, "emailAddress": "[email protected]", "isPrimary": true, ... }],
"addresses": [{ "id": 6201, "line1": "1 Market St", "isPrimary": true, ... }],
"isActive": true,
"createdAt": "2026-05-06T13:42:01.1234567Z"
}

The id is your handle for every subsequent call — store it on your side before doing anything else. Phone, email, and address rows each get their own server-assigned int ids you’ll see again on the round-trip read.

Terminal window
CONTACT_ID=1834
curl -sS \
-H "X-Api-Key: $AURA_API_KEY" \
"https://api.auradonors.com/api/tenants/$TENANT_ID/contacts/$CONTACT_ID/dashboard"

The dashboard endpoint is the one-round-trip aggregate that the contact detail page uses internally. It’s heavier than GET /contacts/{id} (it includes recent orders, recurring schedules, tags, organizations, relationships, and Mailchimp memberships) but much cheaper than calling each child endpoint separately.

If you only need the identity fields, use GET /contacts/{contactId} instead.

StatusBody’s errors shapeWhat to do
400{"FirstName": ["First name is required for individuals."]}Set required fields per contactType.
400{"Emails[0].EmailAddress": ["Not a valid email address."]}Fix the offending child row.
400{"": ["Contact source is required for new contacts."]}Look up valid contactSourceIds under Administration → Reference Data → Contact Sources and include contactSourceId on the request.
403{"title": "Missing required permission: contacts:create"}Add the scope to your API key and rotate.

If your integration imports contacts from another system and you want to avoid creating duplicates, call the duplicate-check endpoint first:

Terminal window
curl -sS -X POST \
-H "X-Api-Key: $AURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contactType": "Individual",
"firstName": "Jane",
"lastName": "Donor",
"emails": ["[email protected]"],
"phones": ["+1-415-555-0142"],
"addresses": [{ "line1": "1 Market St", "postalCode": "94105" }]
}' \
"https://api.auradonors.com/api/tenants/$TENANT_ID/contacts/check-duplicates"

The response lists candidate matches with confidence scores so your code can decide between “merge into the existing record” and “create new.”

  • The contact you just created is now eligible to receive donations, tasks, attachments, etc. See Record a donation for the next step.
  • Track future changes by subscribing to contact.updated and contact.deleted — see Listen for events.