Core

Tags

Tags label contacts for segmentation. Most integrations never call these endpoints directly — they sync state and let automations apply tags. But you can add or remove a tag explicitly when you need to.

Prefer letting automations tag for you

Instead of hardcoding tag logic in your app, sync the underlying field (e.g. custom_fields.plan) and configure an automation in Meisa to add paying-customer when the plan becomes paid. Your code stays simple and the marketing team controls the rules. See How automations work.

Add a tag

POST/contacts/{id}/add_tag/scope: contacts:write

Adds a tag to a contact, creating the tag if it doesn't exist. {id} is the contact's Meisa id (returned by upsert). Pass tag_name (the convenient option) or tag_id.

add a tag
curl -X POST "https://api.meisa.io/api/v1/contacts/550e8400-.../add_tag/" \
  -H "X-API-Key: meisa_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "tag_name": "churned" }'

Remove a tag

POST/contacts/{id}/remove_tag/scope: contacts:write

Removes a tag from a contact. Pass tag_name or tag_id.

remove a tag
curl -X POST "https://api.meisa.io/api/v1/contacts/550e8400-.../remove_tag/" \
  -H "X-API-Key: meisa_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "tag_name": "trial" }'

Tag changes are authorized by the contacts:write scope. You don't need a separate tags scope. Adding or removing a tag can fire matching tag_added / tag_removed automations.

Adding tags during upsert

You can also add tags inline when you sync a contact, via the tag_names array on upsert. That only adds tags (never removes them), which is handy for stamping a known label as part of the same call.