SendyStack
Contacts

Manage your contact list

Contacts are the recipients of your broadcasts. Each contact has a phone number, optional custom attributes, opt-in / out state, and tags.

Endpoints

GET/internal/contactsDashboard Onlydashboard session

List recent contacts (up to 500) with their tags, attributes, and opt-in state.

Requires an authenticated dashboard session — your wac_live_ API key cannot call this endpoint. Use it from inside the dashboard, or wrap it behind your own server.

POST/internal/contactsDashboard Onlyowner / admin / developer

Create or update one contact. Idempotent on phone — a duplicate phone updates the existing record.

Requires an authenticated dashboard session — your wac_live_ API key cannot call this endpoint. Use it from inside the dashboard, or wrap it behind your own server.

POST/internal/contacts/bulkDashboard Onlyowner / admin / developer

Bulk-create up to 1,000 contacts at a time. Returns per-row results.

Requires an authenticated dashboard session — your wac_live_ API key cannot call this endpoint. Use it from inside the dashboard, or wrap it behind your own server.

PATCH/internal/contacts/:idDashboard Onlyowner / admin / developer

Patch a contact's name, attributes, or tags.

Requires an authenticated dashboard session — your wac_live_ API key cannot call this endpoint. Use it from inside the dashboard, or wrap it behind your own server.

Create one contact

Phones are normalized to +digits form. Use any custom attribute keys you like — they'll resolve into {{n}} placeholders in templates that reference them.

POST /internal/contacts
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "name": "Jane Doe",
  "phone": "+254700000000",
  "country": "KE",
  "attributes": {
    "rent_amount": "25000",
    "invoice_no": "ALF-0042"
  }
}

Bulk import

POST /internal/contacts/bulk
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "contacts": [
    { "name": "Sarah", "phone": "+254700112233" },
    { "name": "Brian", "phone": "+254700112244" }
  ]
}

CSV imports use the same payload — the dashboard's CSV importer just maps spreadsheet columns into this body.