{
    "openapi": "3.0.3",
    "info": {
        "title": "ZupiChat API",
        "version": "1.0.0",
        "description": "Send WhatsApp template messages, manage contacts and receive delivery events from your own application. ZupiChat is operated by Codelith Lab Private Limited and runs on the WhatsApp Cloud API.",
        "termsOfService": "https://www.zupichat.com/policy/terms-of-service",
        "contact": {
            "name": "ZupiChat support",
            "url": "https://www.zupichat.com/developers",
            "email": "support@zupichat.com"
        }
    },
    "externalDocs": {
        "description": "Developer documentation",
        "url": "https://www.zupichat.com/developers"
    },
    "servers": [
        {
            "url": "https://www.zupichat.com/api/v1",
            "description": "Production"
        }
    ],
    "tags": [
        {
            "name": "Account",
            "description": "Check a key and the number it is bound to"
        },
        {
            "name": "Templates",
            "description": "Templates Meta has approved for this number"
        },
        {
            "name": "Messages",
            "description": "Send a template and follow its delivery"
        },
        {
            "name": "Contacts",
            "description": "Read the contact book, or push a lead into it"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        },
        {
            "apiKeyHeader": []
        },
        {
            "apiKeyQuery": []
        }
    ],
    "paths": {
        "/me": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Who this key belongs to",
                "description": "Confirms the key works and tells you which WhatsApp number it is bound to. Useful as a health check right after a customer pastes their key into your product.",
                "operationId": "getMe",
                "responses": {
                    "200": {
                        "description": "The account behind the key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "OK",
                                    "data": {
                                        "account": {
                                            "id": 13,
                                            "name": "Aditya Sonawane",
                                            "email": "owner@example.com"
                                        },
                                        "whatsapp": {
                                            "connected": true,
                                            "display_name": "Zupi Chat",
                                            "phone_number": "918329608019",
                                            "phone_number_id": "1164348036759819"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The account behind the key is inactive.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/templates": {
            "get": {
                "tags": [
                    "Templates"
                ],
                "summary": "List approved templates",
                "description": "Lists the message templates on the connected WhatsApp Business Account that Meta has approved, so you can show your users only what can actually be sent. Newest first, up to 200.",
                "operationId": "listTemplates",
                "responses": {
                    "200": {
                        "description": "Approved templates.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "OK",
                                    "data": {
                                        "templates": [
                                            {
                                                "id": 18,
                                                "name": "zupichat_new_offer",
                                                "language": "en_US",
                                                "category": {
                                                    "id": 1,
                                                    "name": "MARKETING",
                                                    "label": "Marketing"
                                                },
                                                "status": "APPROVED"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/messages/template": {
            "post": {
                "tags": [
                    "Messages"
                ],
                "summary": "Send a template message",
                "description": "Template messages are the only way to start a conversation outside WhatsApp's 24-hour window, which is why this is the endpoint most integrations need. The contact and the conversation are created on the first send, exactly as an inbound message would create them.",
                "operationId": "sendTemplateMessage",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SendTemplateRequest"
                            },
                            "example": {
                                "destination": "919876543210",
                                "template_name": "order_confirmation_update",
                                "name": "Aditya",
                                "body_variables": [
                                    "Aditya",
                                    "#1042"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Handed to WhatsApp.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "Template message queued with WhatsApp.",
                                    "data": {
                                        "message_id": 2340,
                                        "whatsapp_message_id": "wamid.HBgMOTE4MzI5NjA4MDE5FQIAERgSMEE4...",
                                        "campaign_id": 61,
                                        "conversation_id": 74,
                                        "contact_id": 187,
                                        "contact_created": false,
                                        "status": "sent"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No approved template matches that name or id.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "No WhatsApp number is connected, or the contact is blocked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A field is missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "WhatsApp rejected the send; the message repeats what Meta said.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/messages/{id}": {
            "get": {
                "tags": [
                    "Messages"
                ],
                "summary": "Delivery status of one message",
                "description": "Returns what WhatsApp last reported for that message — sent, delivered, read or failed. Poll it if you are not using webhooks.",
                "operationId": "getMessageStatus",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "The message_id returned when you sent it.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 2340
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Last known status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "OK",
                                    "data": {
                                        "message_id": 2340,
                                        "whatsapp_message_id": "wamid.HBgMOTE4MzI5NjA4MDE5FQIAERgSMEE4...",
                                        "status": "delivered",
                                        "sent_at": "2026-08-22T11:08:04+05:30"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The message does not belong to this account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/contacts": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "summary": "List contacts",
                "description": "Reads the contact book, newest first.",
                "operationId": "listContacts",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Rows per page, 200 maximum.",
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        },
                        "example": 50
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Page number, starting at 1.",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Matches name or mobile number.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "One page of contacts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "OK",
                                    "data": {
                                        "contacts": [
                                            {
                                                "id": 187,
                                                "name": "Aditya Sonawane",
                                                "mobile": "919876543210",
                                                "blocked": false,
                                                "created": "2026-08-22T00:24:35+05:30"
                                            }
                                        ],
                                        "pagination": {
                                            "page": 1,
                                            "pages": 2,
                                            "total": 90
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Contacts"
                ],
                "summary": "Create or update a contact",
                "description": "Pushes a lead into the contact book the moment it appears in your own system. Matching is by mobile number, so calling this twice updates rather than duplicates.",
                "operationId": "storeContact",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreContactRequest"
                            },
                            "example": {
                                "mobile": "919876543210",
                                "firstname": "Aditya",
                                "note": "Came from the pricing page"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Contact saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                "example": {
                                    "success": true,
                                    "message": "Contact created.",
                                    "data": {
                                        "contact_id": 189,
                                        "created": true,
                                        "name": "Aditya Sonawane",
                                        "mobile": "919876543210"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No key was sent, or the key is invalid or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "A field is missing or malformed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Authorization: Bearer zc_live_xxxxxxxxxxxxxxxx. A zc_test_ key runs the same endpoints in test mode: fixtures instead of live data, nothing sent to Meta, nothing billed."
            },
            "apiKeyHeader": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key",
                "description": "Same key, for clients that cannot set an Authorization header."
            },
            "apiKeyQuery": {
                "type": "apiKey",
                "in": "query",
                "name": "apiKey",
                "description": "Last resort for no-code tools. Prefer a header — query strings end up in logs."
            }
        },
        "schemas": {
            "Envelope": {
                "type": "object",
                "description": "Every response uses this shape, so a client can branch on one field.",
                "properties": {
                    "success": {
                        "type": "boolean"
                    },
                    "message": {
                        "type": "string"
                    },
                    "data": {
                        "type": "object"
                    }
                },
                "required": [
                    "success",
                    "message"
                ]
            },
            "Error": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": false
                    },
                    "message": {
                        "type": "string",
                        "example": "Invalid or revoked API key."
                    },
                    "errors": {
                        "type": "object",
                        "description": "Field-by-field detail, on a 422 only."
                    }
                }
            },
            "SendTemplateRequest": {
                "type": "object",
                "required": [
                    "destination"
                ],
                "properties": {
                    "destination": {
                        "type": "string",
                        "maxLength": 20,
                        "description": "Recipient in international format, digits only, country code included.",
                        "example": "919876543210"
                    },
                    "template_name": {
                        "type": "string",
                        "maxLength": 120,
                        "description": "Name of an approved template. Send this or template_id.",
                        "example": "order_confirmation_update"
                    },
                    "template_id": {
                        "type": "integer",
                        "description": "ZupiChat's own id for the template. Send this or template_name."
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 80,
                        "description": "Contact name to save when this number is new to the account."
                    },
                    "campaign_name": {
                        "type": "string",
                        "maxLength": 120,
                        "description": "Groups the send under a standing API campaign in reports."
                    },
                    "body_variables": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Values for {{1}}, {{2}} … in body order."
                    },
                    "header_variables": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Values for a variable in the header, if the template has one."
                    }
                }
            },
            "StoreContactRequest": {
                "type": "object",
                "required": [
                    "mobile"
                ],
                "properties": {
                    "mobile": {
                        "type": "string",
                        "maxLength": 20,
                        "description": "International format, country code included.",
                        "example": "919876543210"
                    },
                    "firstname": {
                        "type": "string",
                        "maxLength": 60
                    },
                    "lastname": {
                        "type": "string",
                        "maxLength": 60
                    },
                    "note": {
                        "type": "string",
                        "maxLength": 500
                    }
                }
            }
        }
    },
    "x-sandbox": {
        "description": "Test mode needs no WhatsApp Business Account. The public demo key below only simulates; send \"join zupi-demo\" on WhatsApp to the sandbox number and your test sends are delivered to that phone for real for 24 hours.",
        "demoKey": "zc_demo_zupichat_public_sandbox",
        "joinNumber": "918329608019",
        "docs": "https://www.zupichat.com/developers#testmode"
    },
    "x-webhooks": {
        "message.received": {
            "post": {
                "summary": "message.received",
                "description": "A customer sent a message to your WhatsApp number.",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Envelope"
                            },
                            "example": {
                                "event": "message.received",
                                "created_at": "2026-08-22T11:08:04+05:30",
                                "data": {
                                    "message_id": 2341,
                                    "conversation_id": 74,
                                    "contact_id": 187,
                                    "from": "919876543210",
                                    "name": "Aditya Sonawane",
                                    "type": "text",
                                    "text": "hi"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Answer 2xx within 3 seconds or the delivery is logged as failed."
                    }
                }
            }
        },
        "message.sent": {
            "post": {
                "summary": "message.sent",
                "description": "You sent a message, from the panel or through this API.",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Envelope"
                            },
                            "example": {
                                "event": "message.sent",
                                "created_at": "2026-08-22T11:08:04+05:30",
                                "data": {
                                    "message_id": 2340,
                                    "whatsapp_message_id": "wamid.HBgMOTE4...",
                                    "conversation_id": 74,
                                    "contact_id": 187,
                                    "destination": "919876543210",
                                    "template": "order_confirmation_update",
                                    "source": "api"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Answer 2xx within 3 seconds or the delivery is logged as failed."
                    }
                }
            }
        },
        "message.status": {
            "post": {
                "summary": "message.status",
                "description": "WhatsApp reported a message as sent, delivered, read or failed.",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Envelope"
                            },
                            "example": {
                                "event": "message.status",
                                "created_at": "2026-08-22T11:08:04+05:30",
                                "data": {
                                    "message_id": 2340,
                                    "whatsapp_message_id": "wamid.HBgMOTE4...",
                                    "conversation_id": 74,
                                    "status": "delivered"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Answer 2xx within 3 seconds or the delivery is logged as failed."
                    }
                }
            }
        },
        "contact.created": {
            "post": {
                "summary": "contact.created",
                "description": "A number reached the account for the first time.",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Envelope"
                            },
                            "example": {
                                "event": "contact.created",
                                "created_at": "2026-08-22T11:08:04+05:30",
                                "data": {
                                    "contact_id": 189,
                                    "mobile": "919876543210",
                                    "name": "Aditya Sonawane"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Answer 2xx within 3 seconds or the delivery is logged as failed."
                    }
                }
            }
        }
    }
}