Quickstart
By the end of this guide you’ll have:
- A new end-customer recorded on your Kirimdev org
- A one-time setup link emailed (or DM’d) to that customer
- That customer’s WhatsApp number connected to your platform
- A test message sent from their number to a recipient
Prerequisites
- Kirimdev workspace on the Business plan or above — Customers is plan-gated. Upgrade in Billing settings if
POST /v1/customersreturns 402 (feature_not_entitled). Pro and Starter do not include this feature. - An API key with write scope:
kdv_live_…. Manage keys - Meta Embedded Signup configured on your Facebook app (the same one you use for your own WhatsApp accounts).
-
Install the SDK
Terminal window bun add @kirimdev/sdk# or: npm install @kirimdev/sdk -
Create the customer
import { Kirim } from '@kirimdev/sdk'const kirim = new Kirim({ apiKey: process.env.KIRIM_API_KEY! })const customer = await kirim.customers.create({name: 'Acme Logistics',email: 'admin@acme.io',metadata: { crm_id: 'C-1234', branch: 'Jakarta' },})console.log(customer.id)// → 'cus_335T08RM0EAKN9DTE6RD5RWP7B'Terminal window curl -sS https://api.kirimdev.com/v1/customers \-H 'Authorization: Bearer kdv_live_xxx' \-H 'Content-Type: application/json' \-d '{"name": "Acme Logistics","email": "admin@acme.io","metadata": { "crm_id": "C-1234", "branch": "Jakarta" }}'Customer is created in
status: 'pending'. It transitions toactiveautomatically once the first WhatsApp number connects. -
Generate a setup link
const link = await kirim.customers.createSetupLink(customer.id, {expires_in_hours: 168, // 7 dayssuccess_redirect_url: 'https://yourapp.com/onboarded',failure_redirect_url: 'https://yourapp.com/onboard-failed',})// IMPORTANT: link.token and link.setup_url are returned ONCE.// Persist or relay them now — list/get calls never re-expose them.console.log(link.setup_url)// → 'https://app.kirimdev.com/onboard/csl_3V3EMgPDU4zCTm7Fju7KWvqb'Terminal window curl -sS https://api.kirimdev.com/v1/customers/cus_xxx/setup_links \-H 'Authorization: Bearer kdv_live_xxx' \-H 'Content-Type: application/json' \-d '{"expires_in_hours": 168,"success_redirect_url": "https://yourapp.com/onboarded","failure_redirect_url": "https://yourapp.com/onboard-failed"}' -
Deliver the link to your tenant
Email, in-app message, SMS — however you communicate. The default TTL is 7 days; max 30 days (
expires_in_hours: 720). -
Tenant clicks the link
The Kirimdev onboarding page opens without requiring a Kirimdev login, validates the token, and triggers Meta Embedded Signup against your Facebook app.
On success the tenant is auto-redirected to your
success_redirect_urlwith these query params appended:?customer_id=cus_335T08RM0EAKN9DTE6RD5RWP7B&account_id=wa_internal_id_xxx&status=successOn failure, the URL is your
failure_redirect_urlwithstatus=failed&reason=<code>. -
Listen for
customer.onboardedSubscribe to webhooks so your backend learns the moment a customer finishes onboarding:
await kirim.webhookSubscriptions.create({url: 'https://yourapp.com/webhooks/kirim',events: ['customer.onboarded', 'customer.setup_link.consumed'],})The
customer.onboardedpayload carriesphone_number_id— that’s the value you plug intoPOST /v1/{phone_number_id}/messagesto send on the new account’s behalf. See the full event catalogue. -
Send a test message
const phoneNumberId = '1111475158712095' // from the webhook payloadawait kirim.phoneNumbers(phoneNumberId).messages.send({messaging_product: 'whatsapp',to: '+6285887130408',type: 'text',text: { body: 'Halo dari platform!' },})There is no special code path for customer-owned accounts. The Public API doesn’t distinguish them from direct-org accounts —
phone_number_idis the only identity that matters at send time.
What you just did
Section titled “What you just did”| Step | API call | Result |
|---|---|---|
| Created the customer | POST /v1/customers | customer.status = 'pending' |
| Generated a setup link | POST /v1/customers/{id}/setup_links | Plaintext URL returned once |
| Tenant onboarded via the link | (browser flow) | customer.status = 'active', WA account attached |
| Sent a message | POST /v1/{phone_number_id}/messages | First outbound message on the tenant’s number |
Next steps
Section titled “Next steps”- Customers concept reference — full field list, status lifecycle, multi-team rules.
- Setup links — token hashing, TTL, lifecycle states, revocation.
- Redirect URLs — validation rules, query param contract, common UX patterns.
- Webhook event catalogue — six
customer.*events with payload samples.