01Inbound API reference
Send contacts and tags into Funnels.cm. Every tag request creates or updates the contact for that email, then runs tag automations.
Upsert contact
POST /api/v1/contacts
{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"phone": "+15551234567",
"tagIds": ["tagId123"],
"customFields": { "customFieldId": "Acme Inc" }
}
Use tagNames instead of tagIds if you prefer names: "tagNames": ["Newsletter"].
- Upsert by email (case-insensitive).
tagNames/tagIdson upsert are add-only (existing tags are kept).- Unknown tag names are ignored; invalid tag IDs are skipped. Check the
tagsobject in the response.
Response:
{
"success": true,
"contact": { "id": "contactId123", "email": "[email protected]", "firstName": "Jane", "tagIds": ["tagId123"] },
"created": true,
"tags": {
"requested": { "tagNames": [], "tagIds": ["tagId123"] },
"applied": { "tagNames": ["Newsletter"], "tagIds": ["tagId123"] }
}
}
If no tags matched, the response may include tags.unmatchedTagNames and tags.warning.
List & get contacts
GET /api/v1/[email protected]&limit=50 · GET /api/v1/contacts/:contactId
Tags
GET /api/v1/tags returns { "tags": [{ "id", "name", "order", "createdAt" }, ...] }.
Tag by email - POST /api/v1/contacts/tags
{
"email": "[email protected]",
"tagIds": ["tagId123"],
"action": "add",
"firstName": "Jane"
}
tagNames works the same way. Send either tagIds or tagNames (or both).
action: "add" (default, upserts contact) or "remove" (requires existing contact).
By contact ID - POST /api/v1/contacts/:contactId/tags · { "tagIds": ["tagId123"], "action": "add" }
CRM leads (optional)
POST /api/v1/crms/:crmId/leads - creates a lead and upserts the contact in one call:
{
"title": "Inbound demo request",
"stageId": "stageId123",
"contactEmail": "[email protected]",
"firstName": "Jane",
"tagIds": ["tagId123"]
}
PATCH /api/v1/crms/:crmId/leads/:leadId - update title, stageId, or amount.