Contacts

Create contact

Create one contact. Returns 201 with the contact, or 409 if the email already exists — use POST /contacts/bulk to upsert.

POSThttps://api.sndr.sh/api/cranl/v1/contacts
Create contact
curl -X POST 'https://api.sndr.sh/api/cranl/v1/contacts' \
  -H 'Authorization: Bearer sndr_your_access_token' \
  -H 'Content-Type: application/json' \
  -d '{
    "email":      "jane@example.com",
    "first_name": "Jane",
    "last_name":  "Doe",
    "attributes": { "plan": "pro", "city": "Berlin" },
    "source":     "checkout",
    "group_ids":  ["grp_4d8a0c5e-1f7"]
  }'
201Created
{
  "id":              "con_0e6b7f21-c58",
  "organization_id": "org_8d41c7a2-3f6",
  "email":           "jane@example.com",
  "first_name":      "Jane",
  "last_name":       "Doe",
  "attributes":      { "plan": "pro", "city": "Berlin" },
  "status":          "subscribed",
  "source":          "checkout",
  "created_at":      "2026-06-01T12:00:00Z",
  "updated_at":      "2026-06-01T12:00:00Z"
}

Authorization

Authorizationstringheaderrequired

Bearer followed by an access token. Needs the send scope.

Body

application/json
emailstringrequired

Email address. Stored lowercase and unique per account.

first_namestring

First name, max 100 characters.

last_namestring

Last name, max 100 characters.

statusstring

subscribed (default), unsubscribed, bounced or complained. Only subscribed contacts receive broadcasts.

attributesobject

Free-form key-value data, e.g. {"plan":"pro"}.

sourcestring

Label for where the contact came from. Defaults to manual.

group_idsstring[]

Groups (grp_...) to add the new contact to. Unknown IDs are ignored.

Errors

401unauthenticatedMissing or invalid Bearer token.
401token_expiredAccess token expired — exchange the refresh token for a new pair.
401token_revokedToken was explicitly revoked.
400invalid_requestBody is not valid JSON, has an unknown field, or a field has the wrong type.
403insufficient_scopeToken is missing the send scope.
409conflictA contact with this email already exists.
422validation_failedemail is missing or invalid, a name is over 100 characters, or status is not one of the four values.