Skip to content

Sync your CRM

Your CRM stays the source of truth. Noticia mirrors the customers you want to activate and records their SMS consent. This guide shows the two-call pattern: upsert the profile, then opt the customer in.

Push each customer as a profile keyed on your own external_id. The call is an upsert: safe to repeat, never creates a duplicate. Send it on customer creation and on every change you want reflected (last write wins).

Terminal window
curl https://api.sms.noticia.ai/v1/profiles \
-X POST \
-H "x-api-key: ntca_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{
"external_id": "crm-customer-4815",
"phone_number": "+33612345678",
"first_name": "Camille",
"last_name": "Durand",
"attributes": { "tier": "gold", "favorite_store": "lyon-part-dieu" }
}'

A profile with a phone number is not allowed to receive SMS. You must record an explicit opt-in. Reference the same customer with profile_id and capture where consent came from.

Terminal window
curl https://api.sms.noticia.ai/v1/subscriptions/opt-in \
-X POST \
-H "x-api-key: ntca_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+33612345678",
"profile_id": "crm-customer-4815",
"consent_source": "LOYALTY_PROGRAM",
"consented_at": "2026-05-28T10:00:00.000Z",
"consent_proof": {
"terms_url": "https://brand.example/sms-terms",
"terms_version": "v2.3",
"source_text": "Loyalty signup, Lyon Part-Dieu"
}
}'

The response is an envelope: the resulting subscription under subscription (with status: "SUBSCRIBED"), an outcome (created or resubscribed when the consent is granted — the two outcomes that trigger automations; updated when the number was already subscribed and only its consent proof changed, as on a CRM resync; already_subscribed when nothing changed; superseded when the consent is dated before a more recent consent event: it joins the consent history but does not change the subscription) and an automation object saying whether this consent can trigger automations (a consent older than 7 days is recorded but triggers no journey; the automations themselves run asynchronously after the response, with retries). From now on the customer is reachable by Noticia segments, journeys and campaigns.

{
"subscription": {
"profile": {
"id": "prof_01h455vb4pex5vsknk084sn02q",
"external_id": "crm-customer-4815"
},
"phone_number": "+33612345678",
"status": "SUBSCRIBED",
"consent_source": "LOYALTY_PROGRAM",
"consented_at": "2026-05-28T10:00:00.000Z",
"unsubscribed_at": null,
"consent_proof": {
"terms_url": "https://brand.example/sms-terms",
"terms_version": "v2.3",
"source_text": "Loyalty signup, Lyon Part-Dieu"
}
},
"outcome": "created",
"automation": { "state": "eligible" }
}
  • New customer: upsert the profile, then opt in if they consented.
  • Updated customer: upsert the profile again. Last write wins.
  • Withdrawn consent: call POST /v1/subscriptions/opt-out. A STOP reply does this automatically.

You do not need a full two-way sync. Push what drives activation, keep your CRM authoritative, and let opt-outs flow back through webhooks when that ships.

Wrap each write with an Idempotency-Key so a network retry never creates a duplicate, and handle errors with the recommended back-off.