Skip to content

Contacts and sequences API ​

How do I add or update a contact? ​

POST /contacts. If a contact with that phone number exists, it's updated; otherwise it's created.

bash
curl -X POST https://app.kilichat.com/api/v1/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "919876543210",
    "name": "Priya",
    "attributes": { "city": "Chennai", "order_id": "1042" },
    "tags": ["Website lead"],
    "removeTags": ["Cold"],
    "optedOut": false
  }'
FieldRequiredNotes
phoneYesWith country code.
nameNoUp to 100 characters.
attributesNoContact fields. Merged with what's saved; fields you leave out are kept. Names use letters, numbers and _ (up to 40 characters); values up to 500 characters.
tagsNoTag names to add, up to 20. New tags are created.
removeTagsNoTag names to take off, up to 20.
optedOutNotrue opts the contact out; false opts them back in. Leave it out to keep it as it is.

The response is 201 for a new contact and 200 for an update:

json
{
  "contact": {
    "id": "…",
    "phone": "919876543210",
    "name": "Priya",
    "optedOut": false,
    "tags": ["Website lead"],
    "attributes": { "city": "Chennai", "order_id": "1042" },
    "lastMessageAt": null,
    "createdAt": "2026-11-08T10:00:00.000Z"
  },
  "created": true
}

lastMessageAt is when the customer last messaged you, or null if they never have.

Tags can start sequences

Adding a tag that a sequence starts on adds the contact to that sequence. For example, add Website lead from your website form, and a "New leads" sequence follows up automatically.

Only opt people in with their consent

Use "optedOut": false only when the customer has actually asked to hear from you again.

How do I look up a contact? ​

GET /contacts/:phone:

bash
curl https://app.kilichat.com/api/v1/contacts/919876543210 \
  -H "Authorization: Bearer YOUR_API_KEY"

Returns {"contact": {…}} as above, or 404 with "Contact not found".

How do I use contact fields in messages? ​

Fields you save in attributes can be used anywhere KiliChat fills in values: {{attr.city}} in broadcasts, sequences, flows, template variables and the API itself. To have them show up nicely in KiliChat's pickers, an admin can also add them under Settings → Tags & fields → Contact fields, using a label whose key matches (for example the label "Order ID" has the key order_id).

How do I add a contact to a sequence? ​

First find the sequence's id with GET /sequences:

json
{ "sequences": [ { "id": "3b9d…", "name": "New leads", "active": true, "steps": 3 } ] }

steps is the number of messages in it. Then:

bash
curl -X POST https://app.kilichat.com/api/v1/sequences/3b9d…/enroll \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "919876543210"}'

The contact is created first if needed. Responses:

ResponseMeaning
{"added": true, "contactId": "…"}They're on the sequence.
{"added": false, "contactId": "…", "reason": "Opted out or already on this sequence"}Not added.
404 "Sequence not found"Wrong id, or it belongs to another number.
422 "This sequence is turned off"Turn it on in KiliChat first.

In Node.js ​

js
const API = "https://app.kilichat.com/api/v1";
const headers = {
  Authorization: `Bearer ${process.env.KILICHAT_API_KEY}`,
  "Content-Type": "application/json",
};

// From a website form: save the lead, tag it, and let a sequence follow up.
async function saveLead({ phone, name, city }) {
  const res = await fetch(`${API}/contacts`, {
    method: "POST",
    headers,
    body: JSON.stringify({ phone, name, attributes: { city }, tags: ["Website lead"] }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.error);
  return body.contact;
}

Can I delete contacts or read conversations through the API? ​

No. The API can add and update contacts and send messages, but not delete contacts or read chat history. Use webhooks to receive messages as they arrive.