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.
Required scopes
Section titled “Required scopes”contacts:createcontacts:view(for the round-trip read)
1. Create the contact
Section titled “1. Create the contact”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, ... }], "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.
2. Round-trip the read
Section titled “2. Round-trip the read”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.
Common failures
Section titled “Common failures”| Status | Body’s errors shape | What 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. |
Detecting duplicates before you create
Section titled “Detecting duplicates before you create”If your integration imports contacts from another system and you want to avoid creating duplicates, call the duplicate-check endpoint first:
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.”
What’s next
Section titled “What’s next”- 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.updatedandcontact.deleted— see Listen for events.