Agent-readable docs index: /docs/llms.txt. Full docs in one file: /docs/llms-full.txt. Download /docs/docs.zip to grep all markdown files locally.

Upsert in list

/contact_lists/{list_id}/contactsPOST
The list ID determines where the record is stored. An existing contact in that list is matched by normalized email, phone number, or external customer ID. Custom field keys must be configured in the workspace. Consent and suppression state are not changed. Use a server-side API key with contacts:write scope. Idempotency-Key is optional; reusing it with a different request returns 409.
Authorization
BearerAuth *Bearer <token>
API key generated under Account Settings → API Keys (rk_live_...). Send as header Authorization: Bearer <key>.
Request Bodyapplication/jsonrequired
email?string (email)
Min length: 1
phone_number?string
Min length: 1
external_customer_id?string
Min length: 1
first_name?string
last_name?string
tags?string[]
custom_fields?object
Response
200 · Existing contact in the list updated
Existing contact in the list updated
201 · Contact created in the list
Contact created in the list
401 · Unauthorized
success *boolean
Example: false
error *string
Human-readable error message explaining the failure reason.
Example: "Recipient not reachable on WhatsApp."
error_code *string
Stable machine-readable error code.
Example: "recipient_not_on_whatsapp"
403 · API key lacks contacts:write scope
API key lacks contacts:write scope
404 · List is not in the API key's workspace
List is not in the API key's workspace
409 · Identifiers conflict or idempotency key was reused
Identifiers conflict or idempotency key was reused
422 · Invalid contact fields or values
Invalid contact fields or values
Request example
curl -X POST "https://convert.ruut.chat/api/v1/contact_lists/0/contacts" \ -H "Idempotency-Key: <Idempotency-Key>" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]", "first_name": "Ada" }'
Response example
{ "success": false, "error": "Invalid, expired, or revoked API key.", "error_code": "unauthorized" }