Skip to content

API: Contacts & tags

Contacts are the heart of the CRM, and the API mirrors what the app can do with them — including the consent rules. See the API overview for authentication and errors.

The contact object

{
"id": "0d9f7c3e-…",
"phone": "+4915112345678",
"name": "Ada Example",
"locale": "de",
"source": "api",
"opt_in_status": "confirmed",
"attributes": { "company": "Example GmbH" },
"tags": ["webinar", "vip"],
"last_inbound_at": "2026-07-01T18:22:10Z",
"created_at": "2026-06-12T09:03:44Z"
}

opt_in_status is one of none, pending, confirmed, opted_out. Campaigns only go to confirmed contacts; opted_out contacts are never messaged.

Create or update — POST /v1/contacts

Upserts by phone number: if the phone already exists in the workspace, the contact is updated; otherwise it is created (and the Contact is created automation trigger fires).

Terminal window
curl -s https://app.nybero.com/api/v1/contacts \
-H "Authorization: Bearer $NYBERO_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "0151 1234 5678",
"default_country": "DE",
"name": "Ada Example",
"source": "landingpage",
"attributes": { "company": "Example GmbH" },
"tags": ["webinar"],
"opt_in": true,
"consent_proof": "Checked the WhatsApp opt-in box on example.com/webinar"
}'
  • phone (required) — international format preferred (+4915112345678). National formats work when you send default_country (ISO code, e.g. DE).
  • attributes — free key/value custom fields; keys merge into the contact’s existing attributes.
  • tags — Nybero tags; missing ones are created. Each newly attached tag fires the Tag is added trigger, so this can start automations.
  • opt_in + consent_proof — see consent semantics below.

The response is the contact object plus "created": true|false.

List & search — GET /v1/contacts

Terminal window
curl -s "https://app.nybero.com/api/v1/contacts?search=ada&tag=webinar&opt_in_status=confirmed&limit=50&offset=0" \
-H "Authorization: Bearer $NYBERO_KEY"

Filters combine: search matches name or phone, tag filters by an exact tag name, opt_in_status by consent state. Paginated (data/total/limit/offset).

Read, update, delete

Terminal window
# One contact
curl -s https://app.nybero.com/api/v1/contacts/{id} -H "Authorization: Bearer $NYBERO_KEY"
# Update fields (attributes merge into existing ones)
curl -s -X PATCH https://app.nybero.com/api/v1/contacts/{id} \
-H "Authorization: Bearer $NYBERO_KEY" -H "Content-Type: application/json" \
-d '{"name":"Ada Lovelace","attributes":{"stage":"customer"}}'
# GDPR delete — removes the contact, its consent trail and tag links
curl -s -X DELETE https://app.nybero.com/api/v1/contacts/{id} \
-H "Authorization: Bearer $NYBERO_KEY"

Deleting is the same GDPR erasure the app performs — use it to honour a right-to-erasure request programmatically. It returns 204 No Content.

Tags

Terminal window
# All tags in the workspace
curl -s https://app.nybero.com/api/v1/tags -H "Authorization: Bearer $NYBERO_KEY"
# Add a tag (created if missing; fires the "Tag is added" trigger when newly attached)
curl -s https://app.nybero.com/api/v1/contacts/{id}/tags \
-H "Authorization: Bearer $NYBERO_KEY" -H "Content-Type: application/json" \
-d '{"name":"vip"}'
# Remove a tag
curl -s -X DELETE https://app.nybero.com/api/v1/contacts/{id}/tags/vip \
-H "Authorization: Bearer $NYBERO_KEY"

Tags are Nybero-native (more on tags) — they drive segments and the Tag is added automation trigger, which makes POST …/tags a handy way to kick off a flow for one contact.

Worked example: sync signups from your backend

Your shop backend marks buyers in Nybero so a post-purchase flow runs:

  1. Customer buys → your backend calls POST /v1/contacts with phone, name, opt_in: true (consent collected at checkout), attributes: {"order_id": "A-1042"}.
  2. The same call adds "tags": ["customer"].
  3. In Nybero, an automation with trigger Tag is added (tag customer) sends the approved order-confirmation template and a review request three days later.

No polling, no CSV exports — one HTTP call per purchase.