Docs
Contacts

Create or update many contacts

POSThttps://api.norreach.app/v1/contacts/batch

Up to 100 contacts in one request, each exactly like POST /contacts (use upsert_on to update existing ones). Each row succeeds or fails on its own; the answer lists them in order.

contacts:writeOperation id: batch_contacts
POST/contacts/batch
curl -X POST "https://api.norreach.app/v1/contacts/batch" \
  -H "Authorization: Bearer $NORREACH_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "contacts": [
    {
      "first_name": "Maja",
      "email": "maja.lind@example.com",
      "upsert_on": "email"
    }
  ]
}'
Create or update many contacts
{
  "object": "batch_result",
  "data": [
    {
      "index": 0,
      "status": "created",
      "id": "7d1c3b2a-5e4f-4a1b-9c8d-0e1f2a3b4c5d",
      "error": null
    }
  ],
  "created": 1,
  "updated": 0,
  "failed": 0
}

Authorizations

Authorizationstringheaderrequired

Bearer authentication: send Authorization: Bearer <key>, with an API key or an OAuth access token. The key needs the scope contacts:write. API keys and scopes

Headers

Idempotency-Keystringheader

Any unique string (≤ 255). The same key with the same request returns the first answer for 24 hours.

Body

application/json

contactsobject[]required

Up to 100 contacts, each like POST /contacts.

Show child attributes
contacts[].first_namestringrequired
contacts[].last_namestring
contacts[].emailstring (email) | null
contacts[].phonestring | null

Any common format; stored as E.164. Needs a country code.

contacts[].companystring | null
contacts[].titlestring | null
contacts[].statusenum
One of:newcontactedinterestednot_interestedconvertedmeeting_bookedbad_databad_timingneutralunresponsiveunqualifieddnc
contacts[].stageenum
One of:newcontactedmeetingqualifiedwonlost
contacts[].tagsstring[]
contacts[].assigned_tostring (uuid) | null
contacts[].timezonestring | null
contacts[].linkedin_urlstring (uri) | null
contacts[].attrsobject
contacts[].sourcestring

Where the contact came from (lowercase letters, digits and _). Defaults to api.

contacts[].consentobject

The lawful basis for contacting them. Without it the contact is saved but nothing is sent to them.

Show child attributes
contacts[].consent.basisenumrequired
One of:legitimate_interestconsentcontract
contacts[].consent.sourcestring

Where the basis came from. Defaults to api.

contacts[].upsert_onenum

Update the existing contact with this email (or phone) instead of failing with a conflict.

One of:emailphone

Response

200application/json— Create or update many contacts

object"batch_result"required
dataobject[]required
Show child attributes
data[].indexintegerrequired
data[].statusenumrequired
One of:createdupdatedfailed
data[].idstring (uuid) | nullrequired
data[].errorobject | nullrequired
createdintegerrequired
updatedintegerrequired
failedintegerrequired

Errors

Errors are application/problem+json with a stable code.

StatusCodeMeaning
400bad_requestThe request couldn't be read.
400unknown_fieldThe request has a field this operation doesn't know.
401unauthorizedA valid API key is required.
403insufficient_scopeThis API key doesn't have the scope this operation needs.
403feature_not_enabledThe API isn't switched on for this workspace.
409idempotency_in_progressA request with this Idempotency-Key is still running.
413too_largeThe request body is too large.
422validation_failedThe request has invalid fields.
422idempotency_mismatchThis Idempotency-Key was used with a different request.
429rate_limitedToo many requests. Slow down and try again.
500server_errorSomething went wrong on our side.
503unavailableThe API isn't available right now. Try again shortly.