{"openapi":"3.1.0","info":{"title":"Kirim Public API","version":"1.0.0","description":"Self-service REST API for sending WhatsApp messages, subscribing to events, and managing your inbox programmatically. See docs.kirim.dev for guides and reference.","contact":{"name":"Kirim Support","url":"https://kirim.dev"}},"servers":[{"url":"https://api-kckit.kirim.chat/v1","description":"Production"},{"url":"http://localhost:3000/v1","description":"Local development"}],"tags":[{"name":"Meta","description":"Liveness probe and API-key introspection."},{"name":"Messages","description":"Send and read WhatsApp messages across every supported content type."},{"name":"Templates","description":"List and inspect Meta-approved templates synced to your Kirim org."},{"name":"Conversations","description":"Inspect chats, change assignment and status, attach labels."},{"name":"Contacts","description":"CRUD over the people you exchange messages with, plus label attach + bulk-tag."},{"name":"Labels","description":"Coloured tags for contacts and conversations. Team-scoped per Kirim's internal model."},{"name":"Webhook Subscriptions","description":"Subscribe to events, rotate signing secrets, pause/resume delivery."},{"name":"Webhook Deliveries","description":"Dead-letter queue + replay surface for outbound webhook failures."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Kirim Public API key. Format: `kdv_live_<24-char base64url>`. Issue keys in Settings → API Keys."}},"schemas":{"ApiErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","example":"invalid_request_error"},"code":{"type":"string","example":"invalid_phone_number"},"message":{"type":"string"},"param":{"type":"string"},"request_id":{"type":"string","example":"req_01HXYZABCDEFGHJKMNPQRSTVWX"}},"required":["type","code","message","request_id"]}},"required":["error"]},"Message":{"type":"object","properties":{"id":{"type":"string","example":"msg_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["message"]},"to":{"type":"string"},"type":{"type":"string"},"status":{"type":"string","enum":["queued","pending","sent","delivered","read","failed"]},"created_at":{"type":"string","format":"date-time"},"conversation_id":{"type":"string"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"provider_code":{"type":["number","null"]}},"required":["code","message","provider_code"]}},"required":["id","object","to","type","status","created_at"]},"Template":{"type":"object","properties":{"id":{"type":"string","example":"tmpl_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["template"]},"name":{"type":"string"},"language":{"type":"string"},"status":{"type":"string","enum":["pending","approved","rejected"]},"content":{"type":"string"},"variables":{"type":"array","items":{"type":"string"}},"components":{},"whatsapp_account":{"type":"object","properties":{"phone_number":{"type":["string","null"]}},"required":["phone_number"]},"provider_template_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","name","language","status","content","variables","whatsapp_account","provider_template_id","created_at","updated_at"]},"WebhookSubscription":{"type":"object","properties":{"id":{"type":"string","example":"wbs_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["webhook_subscription"]},"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","paused","disabled"]},"disabled_reason":{"type":["string","null"]},"consecutive_failures":{"type":"integer","minimum":0},"secrets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"sec_01HXYZABCDEFGHJKMNPQRSTVWX"},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"}},"required":["id","created_at","expires_at"]}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"initial_secret":{"type":"string"}},"required":["id","object","url","description","events","status","disabled_reason","consecutive_failures","secrets","created_at","updated_at"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","example":"wbd_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["webhook_delivery"]},"subscription_id":{"type":"string"},"event_type":{"type":"string"},"event_id":{"type":"string"},"status":{"type":"string","enum":["pending","succeeded","failed","dead"]},"attempt_count":{"type":"integer","minimum":0},"last_attempt_at":{"type":["string","null"],"format":"date-time"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"response_status":{"type":["integer","null"]},"response_body_snippet":{"type":["string","null"]},"duration_ms":{"type":["integer","null"]},"replayed_from":{"type":["string","null"]},"payload":{},"created_at":{"type":"string","format":"date-time"}},"required":["id","object","subscription_id","event_type","event_id","status","attempt_count","last_attempt_at","next_attempt_at","response_status","response_body_snippet","duration_ms","replayed_from","created_at"]},"Conversation":{"type":"object","properties":{"id":{"type":"string","example":"cnv_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["conversation"]},"status":{"type":"string","enum":["open","resolved","pending"]},"contact":{"type":"object","properties":{"id":{"type":"string"},"phone_number":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["id","phone_number","name"]},"whatsapp_account":{"type":"object","properties":{"phone_number":{"type":["string","null"]}},"required":["phone_number"]},"assignee":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["id","name","email"]},"unread_count":{"type":"integer","minimum":0},"last_message_at":{"type":["string","null"],"format":"date-time"},"last_inbound_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","status","contact","whatsapp_account","assignee","unread_count","last_message_at","last_inbound_at","created_at","updated_at"]},"Contact":{"type":"object","properties":{"id":{"type":"string","example":"ctc_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["contact"]},"phone_number":{"type":["string","null"]},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"whatsapp_account":{"type":"object","properties":{"phone_number":{"type":["string","null"]}},"required":["phone_number"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","phone_number","name","email","metadata","whatsapp_account","created_at","updated_at"]},"Label":{"type":"object","properties":{"id":{"type":"string","example":"lbl_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["label"]},"name":{"type":"string"},"color":{"type":"string","enum":["gray","red","orange","amber","yellow","lime","green","emerald","teal","sky","blue","violet","pink"]},"team_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","name","color","team_id","created_at","updated_at"]},"MessageListItem":{"type":"object","properties":{"id":{"type":"string","example":"msg_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["message"]},"conversation_id":{"type":"string"},"to":{"type":["string","null"]},"direction":{"type":"string","enum":["inbound","outbound"]},"type":{"type":"string"},"content":{"type":["string","null"]},"media_url":{"type":["string","null"]},"status":{"type":"string","enum":["pending","sent","delivered","read","failed"]},"created_at":{"type":"string","format":"date-time"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"provider_code":{"type":["number","null"]}},"required":["code","message","provider_code"]}},"required":["id","object","conversation_id","to","direction","type","content","media_url","status","created_at"]},"MeResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"organization":{"type":"object","properties":{"id":{"type":"string","example":"org_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["organization"]},"name":{"type":"string"}},"required":["id","object","name"]},"api_key":{"type":"object","properties":{"id":{"type":"string","example":"key_01HXYZABCDEFGHJKMNPQRSTVWX"},"object":{"type":"string","enum":["api_key"]},"label":{"type":"string"},"last4":{"type":"string"}},"required":["id","object","label","last4"]},"rate_limits":{"type":"object","properties":{"tier":{"type":"string"},"write_per_minute":{"type":"integer"},"read_per_minute":{"type":"integer"}},"required":["tier","write_per_minute","read_per_minute"]}},"required":["organization","api_key","rate_limits"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"SendMessageResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Message"},"request_id":{"type":"string"}},"required":["data","request_id"]},"GetMessageResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Message"},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListTemplatesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Template"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"GetTemplateResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Template"},"request_id":{"type":"string"}},"required":["data","request_id"]},"CreateWebhookSubscriptionResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookSubscription"},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListWebhookSubscriptionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookSubscription"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"GetWebhookSubscriptionResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookSubscription"},"request_id":{"type":"string"}},"required":["data","request_id"]},"UpdateWebhookSubscriptionResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookSubscription"},"request_id":{"type":"string"}},"required":["data","request_id"]},"DeleteWebhookSubscriptionResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","enum":[true]}},"required":["id","deleted"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"AddWebhookSecretResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["webhook_secret"]},"secret":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"}},"required":["id","object","secret","created_at","expires_at"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"DeleteWebhookSecretResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","enum":[true]}},"required":["id","deleted"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListWebhookDeliveriesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"GetWebhookDeliveryResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookDelivery"},"request_id":{"type":"string"}},"required":["data","request_id"]},"ReplayWebhookDeliveryResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["webhook_delivery"]},"replayed_from":{"type":"string"},"status":{"type":"string","enum":["pending"]}},"required":["id","object","replayed_from","status"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"BulkReplayResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"enqueued":{"type":"integer","minimum":0},"capped":{"type":"boolean"}},"required":["enqueued","capped"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListConversationsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"GetConversationResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Conversation"},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListContactsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"GetContactResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListMessagesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageListItem"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"CreateContactResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string"}},"required":["data","request_id"]},"UpdateContactResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string"}},"required":["data","request_id"]},"DeleteContactResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["contact"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"AttachContactLabelResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"contact_id":{"type":"string"},"label_id":{"type":"string"},"attached":{"type":"boolean","enum":[true]}},"required":["contact_id","label_id","attached"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"DetachContactLabelResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"contact_id":{"type":"string"},"label_id":{"type":"string"},"attached":{"type":"boolean","enum":[false]}},"required":["contact_id","label_id","attached"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"BulkLabelContactsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"applied":{"type":"integer","minimum":0},"skipped_cross_org":{"type":"integer","minimum":0},"skipped_team_mismatch":{"type":"integer","minimum":0}},"required":["applied","skipped_cross_org","skipped_team_mismatch"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"UpdateConversationResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Conversation"},"request_id":{"type":"string"}},"required":["data","request_id"]},"AttachConversationLabelResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"conversation_id":{"type":"string"},"label_id":{"type":"string"},"attached":{"type":"boolean","enum":[true]}},"required":["conversation_id","label_id","attached"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"DetachConversationLabelResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"conversation_id":{"type":"string"},"label_id":{"type":"string"},"attached":{"type":"boolean","enum":[false]}},"required":["conversation_id","label_id","attached"]},"request_id":{"type":"string"}},"required":["data","request_id"]},"ListLabelsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Label"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]},"request_id":{"type":"string"}},"required":["data","has_more","next_cursor","request_id"]},"CreateLabelResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Label"},"request_id":{"type":"string"}},"required":["data","request_id"]},"GetLabelResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Label"},"request_id":{"type":"string"}},"required":["data","request_id"]},"UpdateLabelResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Label"},"request_id":{"type":"string"}},"required":["data","request_id"]},"DeleteLabelResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["label"]},"deleted":{"type":"boolean","enum":[true]}},"required":["id","object","deleted"]},"request_id":{"type":"string"}},"required":["data","request_id"]}},"parameters":{}},"paths":{"/health":{"get":{"tags":["Meta"],"summary":"Liveness probe","description":"Unauthenticated health check. Returns 200 if the API is up.","responses":{"200":{"description":"API is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"]},"request_id":{"type":"string"}},"required":["data","request_id"]}}}}}}},"/me":{"get":{"tags":["Meta"],"summary":"Introspect the calling API key","description":"Returns the organization, API key, and rate-limit tier associated with the bearer token. Use to verify key validity from automation scripts.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"API key context","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/messages":{"post":{"tags":["Messages"],"summary":"Send a WhatsApp message","description":"Send a message of any supported type (text, template, image, document, video, audio, interactive). Pass `Idempotency-Key` to safely retry on network failure.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Optional idempotency token. See /docs/idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["text"]},"text":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":4096}},"required":["body"]}},"required":["to","type","text"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["image"]},"image":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"caption":{"type":"string","maxLength":1024},"filename":{"type":"string","maxLength":255}},"required":["url"]}},"required":["to","type","image"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["document"]},"document":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"caption":{"type":"string","maxLength":1024},"filename":{"type":"string","maxLength":255}},"required":["url"]}},"required":["to","type","document"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["video"]},"video":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"caption":{"type":"string","maxLength":1024},"filename":{"type":"string","maxLength":255}},"required":["url"]}},"required":["to","type","video"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["audio"]},"audio":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"caption":{"type":"string","maxLength":1024},"filename":{"type":"string","maxLength":255}},"required":["url"]}},"required":["to","type","audio"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["template"]},"template":{"type":"object","properties":{"name":{"type":"string","minLength":1},"language":{"type":"string","minLength":2},"components":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["header","body","button"]},"sub_type":{"type":"string","enum":["url","quick_reply","copy_code","flow"]},"index":{"type":"integer","minimum":0},"parameters":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["type"]}}},"required":["name","language"]}},"required":["to","type","template"]},{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"to":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"type":{"type":"string","enum":["interactive"]},"interactive":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["cta_url"]},"body":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":1024}},"required":["text"]},"action":{"type":"object","properties":{"name":{"type":"string","enum":["cta_url"]},"parameters":{"type":"object","properties":{"display_text":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["display_text","url"]}},"required":["name","parameters"]}},"required":["type","body","action"]},{"type":"object","properties":{"type":{"type":"string","enum":["list"]},"header":{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":60}},"required":["type","text"]},"body":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":1024}},"required":["text"]},"footer":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":60}},"required":["text"]},"action":{"type":"object","properties":{"button":{"type":"string","minLength":1,"maxLength":20},"sections":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","maxLength":24},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":24},"description":{"type":"string","maxLength":72}},"required":["id","title"]},"minItems":1}},"required":["rows"]},"minItems":1}},"required":["button","sections"]}},"required":["type","body","action"]}]}},"required":["to","type","interactive"]}]}}}},"responses":{"200":{"description":"Message accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"422":{"description":"Semantic failure (e.g. idempotency key reuse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"502":{"description":"Upstream WhatsApp error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"get":{"tags":["Messages"],"summary":"List messages","description":"List messages across the organization. Filter by `conversation_id`, `direction`, `status`, or a `created_after`/`created_before` window.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^cnv_[0-9A-HJKMNP-TV-Z]{26}$"},"required":false,"name":"conversation_id","in":"query"},{"schema":{"type":"string","enum":["inbound","outbound"]},"required":false,"name":"direction","in":"query"},{"schema":{"type":"string","enum":["pending","sent","delivered","read","failed"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"created_after","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"created_before","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Message list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMessagesResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/messages/{id}":{"get":{"tags":["Messages"],"summary":"Fetch a sent message by id","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^msg_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Message resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMessageResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/templates":{"get":{"tags":["Templates"],"summary":"List approved templates","description":"List templates synced from Meta across every connected WhatsApp account in the organization. Default filter is `status=approved`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["approved","pending","rejected","all"],"default":"approved"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":15},"required":false,"name":"language","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Template list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTemplatesResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/templates/{name}":{"get":{"tags":["Templates"],"summary":"Fetch a single template by name","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":512},"required":true,"name":"name","in":"path"},{"schema":{"type":"string","minLength":2,"maxLength":15},"required":false,"name":"language","in":"query"}],"responses":{"200":{"description":"Template resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTemplateResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_subscriptions":{"post":{"tags":["Webhook Subscriptions"],"summary":"Create a webhook subscription","description":"Create a webhook subscription. The response carries `initial_secret` ONCE — store it server-side immediately; Kirim cannot show it again.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":"string","maxLength":200},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.status","conversation.assigned","conversation.closed","contact.created","contact.updated"]},"minItems":1}},"required":["url","events"]}}}},"responses":{"200":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookSubscriptionResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"get":{"tags":["Webhook Subscriptions"],"summary":"List webhook subscriptions","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["active","paused","disabled","all"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Subscription list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWebhookSubscriptionsResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_subscriptions/{id}":{"get":{"tags":["Webhook Subscriptions"],"summary":"Fetch one webhook subscription","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Subscription resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWebhookSubscriptionResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"patch":{"tags":["Webhook Subscriptions"],"summary":"Update a webhook subscription","description":"Toggle status (active/paused), update URL/events/description.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"description":{"type":["string","null"],"maxLength":200},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.status","conversation.assigned","conversation.closed","contact.created","contact.updated"]},"minItems":1},"status":{"type":"string","enum":["active","paused"]}}}}}},"responses":{"200":{"description":"Updated subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookSubscriptionResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"delete":{"tags":["Webhook Subscriptions"],"summary":"Delete a webhook subscription","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWebhookSubscriptionResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_subscriptions/{id}/secrets":{"post":{"tags":["Webhook Subscriptions"],"summary":"Add a new signing secret (rotation)","description":"Issue a new signing secret with the given expiry. During the overlap window every active secret is used to sign outbound deliveries; subscribers verify against any of them.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in_hours":{"type":"integer","minimum":1,"maximum":336}}}}}},"responses":{"200":{"description":"New secret created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWebhookSecretResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"409":{"description":"Conflict (e.g. webhook subscription disabled)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"503":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_subscriptions/{id}/secrets/{secret_id}":{"delete":{"tags":["Webhook Subscriptions"],"summary":"Revoke a signing secret","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^sec_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"secret_id","in":"path"}],"responses":{"200":{"description":"Secret revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWebhookSecretResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"422":{"description":"Semantic failure (e.g. idempotency key reuse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_deliveries":{"get":{"tags":["Webhook Deliveries"],"summary":"List webhook deliveries","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"required":false,"name":"subscription_id","in":"query"},{"schema":{"type":"string","enum":["pending","succeeded","failed","dead"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":64},"required":false,"name":"event_type","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"created_after","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"created_before","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Delivery list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWebhookDeliveriesResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_deliveries/{id}":{"get":{"tags":["Webhook Deliveries"],"summary":"Fetch one delivery (with full payload)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbd_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Delivery resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetWebhookDeliveryResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_deliveries/{id}/replay":{"post":{"tags":["Webhook Deliveries"],"summary":"Replay a single delivery","description":"Re-fire a single delivery against the original subscription URL. Creates a fresh delivery row; the original stays for audit.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^wbd_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Replay enqueued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayWebhookDeliveryResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"409":{"description":"Conflict (e.g. webhook subscription disabled)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/webhook_deliveries/bulk_replay":{"post":{"tags":["Webhook Deliveries"],"summary":"Replay deliveries in bulk (DLQ)","description":"Replay every delivery for a subscription matching the filter, capped at 1000 per request. Paginate via `created_after` / `created_before` for larger backfills.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"subscription_id":{"type":"string","pattern":"^wbs_[0-9A-HJKMNP-TV-Z]{26}$"},"status":{"type":"string","enum":["failed","dead"],"default":"dead"},"event_type":{"type":"string","minLength":1,"maxLength":64},"created_after":{"type":"string","format":"date-time"},"created_before":{"type":"string","format":"date-time"}},"required":["subscription_id"]}}}},"responses":{"200":{"description":"Bulk replay enqueued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkReplayResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"409":{"description":"Conflict (e.g. webhook subscription disabled)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/conversations":{"get":{"tags":["Conversations"],"summary":"List conversations","description":"List conversations across every connected WhatsApp account in the organization. Ordered newest-active first by `last_message_at` (NULLS LAST).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["open","resolved","pending"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":false,"name":"contact_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Conversation list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListConversationsResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/conversations/{id}":{"get":{"tags":["Conversations"],"summary":"Fetch a conversation by id","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^cnv_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Conversation resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetConversationResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"patch":{"tags":["Conversations"],"summary":"Update a conversation","description":"Update status (`open` / `resolved` / `pending`) and/or `assigned_to` (user id, or `null` to clear). At least one field must be present.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^cnv_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["open","resolved","pending"]},"assigned_to":{"type":["string","null"],"minLength":1,"maxLength":64}}}}}},"responses":{"200":{"description":"Updated conversation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConversationResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/contacts":{"get":{"tags":["Contacts"],"summary":"List contacts","description":"List contacts in the organization. Filter by exact `phone` (E.164) or partial `search` (matches name and email).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"required":false,"name":"phone","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":200},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Contact list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContactsResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"post":{"tags":["Contacts"],"summary":"Create a contact","description":"Create a contact attached to a connected WhatsApp account. Single-account orgs auto-resolve; multi-account orgs MUST pass `from`.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"phone_number":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"name":{"type":"string","minLength":1,"maxLength":200},"email":{"type":["string","null"],"maxLength":255,"format":"email"},"metadata":{"type":"object","additionalProperties":{}}},"required":["phone_number"]}}}},"responses":{"200":{"description":"Contact created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"422":{"description":"Semantic failure (e.g. idempotency key reuse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/contacts/{id}":{"get":{"tags":["Contacts"],"summary":"Fetch a contact by id","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Contact resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetContactResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"patch":{"tags":["Contacts"],"summary":"Update a contact","description":"Patch name, email, or metadata. Phone number is the identity column and cannot be changed via the API.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":["string","null"],"minLength":1,"maxLength":200},"email":{"anyOf":[{"type":"string","maxLength":255,"format":"email"},{"type":"string","enum":[""]},{"type":"null"}]},"metadata":{"type":["object","null"],"additionalProperties":{}}}}}}},"responses":{"200":{"description":"Updated contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"delete":{"tags":["Contacts"],"summary":"Delete a contact","description":"Hard-deletes the contact and cascades to its conversations, messages, and label attachments. Irreversible.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteContactResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/messages/{id}/media":{"get":{"tags":["Messages"],"summary":"Redirect to the media asset for a message","description":"Returns a 302 redirect to the underlying CDN URL when the message has media (image, document, video, audio). Returns 404 if the message has no media or if media download is still in flight.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^msg_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"302":{"description":"Redirect to the media URL","headers":{"Location":{"description":"Public CDN URL for the asset","schema":{"type":"string"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/contacts/{id}/labels":{"post":{"tags":["Contacts"],"summary":"Attach a label to a contact","description":"Idempotent — attaching the same label twice is a no-op. The label and the contact must belong to the same team.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label_id":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"}},"required":["label_id"]}}}},"responses":{"200":{"description":"Attached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachContactLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/contacts/{id}/labels/{label_id}":{"delete":{"tags":["Contacts"],"summary":"Detach a label from a contact","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"label_id","in":"path"}],"responses":{"200":{"description":"Detached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetachContactLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/contacts/bulk_label":{"post":{"tags":["Contacts"],"summary":"Attach or detach a label across many contacts","description":"Apply or remove a label from up to 1000 contacts in a single transaction. Cross-org or team-mismatched contacts are silently skipped and counted.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","items":{"type":"string","pattern":"^ctc_[0-9A-HJKMNP-TV-Z]{26}$"},"minItems":1,"maxItems":1000},"label_id":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"operation":{"type":"string","enum":["attach","detach"]}},"required":["contact_ids","label_id","operation"]}}}},"responses":{"200":{"description":"Bulk operation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLabelContactsResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/conversations/{id}/labels":{"post":{"tags":["Conversations"],"summary":"Attach a label to a conversation","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^cnv_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label_id":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"}},"required":["label_id"]}}}},"responses":{"200":{"description":"Attached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachConversationLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/conversations/{id}/labels/{label_id}":{"delete":{"tags":["Conversations"],"summary":"Detach a label from a conversation","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^cnv_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"label_id","in":"path"}],"responses":{"200":{"description":"Detached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetachConversationLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/labels":{"get":{"tags":["Labels"],"summary":"List labels","description":"List labels across every team in the organization.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Label list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLabelsResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"post":{"tags":["Labels"],"summary":"Create a label","description":"Create a label. Single-team orgs auto-resolve `team_id`; multi-team orgs MUST pass it. Names are unique per team — duplicates return `invalid_field_value`.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"team_id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string","minLength":1,"maxLength":50},"color":{"type":"string","enum":["gray","red","orange","amber","yellow","lime","green","emerald","teal","sky","blue","violet","pink"],"default":"gray"}},"required":["name"]}}}},"responses":{"200":{"description":"Label created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}},"/labels/{id}":{"get":{"tags":["Labels"],"summary":"Fetch a label by id","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Label resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"patch":{"tags":["Labels"],"summary":"Update a label","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":50},"color":{"type":"string","enum":["gray","red","orange","amber","yellow","lime","green","emerald","teal","sky","blue","violet","pink"]}}}}}},"responses":{"200":{"description":"Updated label","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}},"delete":{"tags":["Labels"],"summary":"Delete a label","description":"Hard-deletes the label and cascades to every contact and conversation it was attached to (the row in the join table goes away, the parent resources stay).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^lbl_[0-9A-HJKMNP-TV-Z]{26}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteLabelResponse"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"401":{"description":"Authentication failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorEnvelope"}}}}}}}},"webhooks":{}}