{
    "openapi": "3.0.3",
    "info": {
        "title": "WhatsApp Gateway API",
        "version": "1.0.0",
        "description": "Public API contract for WhatsApp Gateway customer integrations. Built for transactional, operational, support, internal, and authentication-style messaging. Marketing, cold outreach, and bulk campaigns are not allowed."
    },
    "servers": [
        {
            "url": "https://evoapi.faisak.com"
        }
    ],
    "tags": [
        {
            "name": "Messages",
            "description": "Public customer API for guarded message sending."
        },
        {
            "name": "Customer Webhooks",
            "description": "Schemas for events delivered by WhatsApp Gateway to customer-configured webhook URLs. Customer webhook requests include X-WhatsApp-Gateway-Event, X-WhatsApp-Gateway-Timestamp, and, when configured, X-WhatsApp-Gateway-Signature. The signature header is sha256=<hmac_hex>, where hmac_hex is HMAC-SHA256 of timestamp + \".\" + raw_body using the customer webhook signing secret."
        },
        {
            "name": "3CX Middleware",
            "description": "3CX integration webhook endpoint and event schema."
        }
    ],
    "paths": {
        "/api/send-message": {
            "post": {
                "tags": [
                    "Messages"
                ],
                "summary": "Send a guarded WhatsApp message",
                "description": "Sends a transactional, operational, support, internal team, or authentication-style WhatsApp message through a customer-owned WhatsApp Gateway instance. Marketing, cold outreach, political, and bulk campaign messages are not allowed.",
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SendMessageRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Message sent.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SendMessageSuccess"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid JSON.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, or revoked API key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Module, plan, suppression, or policy denial.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Instance not found for this customer.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "415": {
                        "description": "This endpoint requires application/json.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error or message purpose error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "423": {
                        "description": "Instance paused for responsible messaging review.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Message limit or velocity control exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Unexpected server error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Delivery could not be completed after responsible messaging checks.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/integrations/3cx/webhook/{integration_id}": {
            "post": {
                "tags": [
                    "3CX Middleware"
                ],
                "summary": "Receive a 3CX middleware webhook event",
                "description": "Receives 3CX middleware events such as test, outbound_message, inbound_reply, missed_call, call_started, call_ended, voicemail, queue_event, queue_callback, and after_hours. Pre-authentication failures return invalid_3cx_webhook with a generic message.",
                "security": [
                    {
                        "ThreeCxSecret": []
                    }
                ],
                "parameters": [
                    {
                        "name": "integration_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        },
                        "description": "3CX integration identifier from the WhatsApp Gateway dashboard."
                    },
                    {
                        "name": "X-WhatsApp-Gateway-Timestamp",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Required when HMAC signing is configured. Unix timestamp used for replay protection."
                    },
                    {
                        "name": "X-WhatsApp-Gateway-Signature",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Required when HMAC signing is configured. Preferred format is sha256=<hex>, where <hex> is HMAC-SHA256 of timestamp + \".\" + raw request body. Bare <hex> signatures are also accepted for compatibility."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ThreeCxWebhookRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "3CX event processed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ThreeCxWebhookResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid JSON or event payload.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Generic pre-authentication webhook failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "3CX module or responsible messaging policy denial.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "413": {
                        "description": "Payload exceeds 256KB.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "3CX webhook rate limit exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Unexpected server error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiError"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "API key",
                "description": "Customer API key created in the WhatsApp Gateway dashboard and sent as Authorization: Bearer CUSTOMER_API_KEY."
            },
            "ThreeCxSecret": {
                "type": "apiKey",
                "in": "header",
                "name": "X-WhatsApp-Gateway-3CX-Secret",
                "description": "3CX integration webhook secret generated in the WhatsApp Gateway dashboard."
            }
        },
        "schemas": {
            "SendMessageRequest": {
                "type": "object",
                "required": [
                    "instance_id",
                    "phone",
                    "message",
                    "message_purpose"
                ],
                "additionalProperties": false,
                "properties": {
                    "instance_id": {
                        "type": "string",
                        "description": "Customer-owned WhatsApp Gateway instance ID or instance name.",
                        "example": "demo-support-line"
                    },
                    "phone": {
                        "type": "string",
                        "description": "Recipient phone number in international format.",
                        "example": "+9665XXXXXXX"
                    },
                    "message": {
                        "type": "string",
                        "description": "Message body to send.",
                        "example": "Your order #2041 has been shipped."
                    },
                    "message_purpose": {
                        "type": "string",
                        "enum": [
                            "transactional",
                            "operational",
                            "support",
                            "internal_team",
                            "authentication"
                        ]
                    }
                }
            },
            "SendMessageSuccess": {
                "type": "object",
                "required": [
                    "success",
                    "status",
                    "message_id",
                    "log_id"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "status": {
                        "type": "string",
                        "example": "sent"
                    },
                    "message_id": {
                        "type": "string",
                        "example": "wamid.example"
                    },
                    "log_id": {
                        "type": "integer",
                        "example": 123
                    }
                }
            },
            "ApiError": {
                "type": "object",
                "required": [
                    "success",
                    "error",
                    "message",
                    "details"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": false
                    },
                    "error": {
                        "type": "string",
                        "example": "message_purpose_not_allowed",
                        "enum": [
                            "unsupported_media_type",
                            "invalid_api_key",
                            "revoked_api_key",
                            "invalid_json",
                            "validation_error",
                            "module_not_enabled",
                            "active_plan_required",
                            "invalid_instance",
                            "message_purpose_required",
                            "message_purpose_not_allowed",
                            "recipient_suppressed",
                            "daily_message_limit_exceeded",
                            "monthly_message_limit_exceeded",
                            "sending_throttled",
                            "instance_paused_for_review",
                            "policy_violation",
                            "gateway_send_failed",
                            "internal_error",
                            "invalid_3cx_webhook",
                            "payload_too_large",
                            "webhook_rate_limited",
                            "missing_phone",
                            "missing_message_text"
                        ]
                    },
                    "message": {
                        "type": "string"
                    },
                    "details": {
                        "type": "object",
                        "additionalProperties": true
                    }
                }
            },
            "WebhookSignatureHeaders": {
                "type": "object",
                "description": "Headers sent with customer webhook deliveries. Verify X-WhatsApp-Gateway-Signature as sha256=<hmac_hex>, where hmac_hex is HMAC-SHA256 of timestamp + \".\" + raw_body using the customer webhook signing secret.",
                "properties": {
                    "X-WhatsApp-Gateway-Event": {
                        "type": "string",
                        "example": "message.received"
                    },
                    "X-WhatsApp-Gateway-Timestamp": {
                        "type": "string",
                        "example": "1778215200"
                    },
                    "X-WhatsApp-Gateway-Signature": {
                        "type": "string",
                        "example": "sha256=example_hmac_signature"
                    }
                }
            },
            "CustomerWebhookEventBase": {
                "type": "object",
                "required": [
                    "event",
                    "instance_id",
                    "instance_name",
                    "timestamp"
                ],
                "properties": {
                    "event": {
                        "type": "string"
                    },
                    "instance_id": {
                        "type": "string",
                        "example": "123"
                    },
                    "instance_name": {
                        "type": "string",
                        "example": "Demo Support Line"
                    },
                    "timestamp": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "MessageReceivedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event",
                            "from",
                            "message_text"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.received"
                                ]
                            },
                            "from": {
                                "type": "string",
                                "example": "+9665XXXXXXX"
                            },
                            "message_text": {
                                "type": "string"
                            },
                            "message_type": {
                                "type": "string",
                                "example": "text"
                            },
                            "external_message_id": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "MessageSentEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event",
                            "to",
                            "message_purpose"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.sent"
                                ]
                            },
                            "to": {
                                "type": "string",
                                "example": "+9665XXXXXXX"
                            },
                            "message_id": {
                                "type": "string"
                            },
                            "message_purpose": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "MessageFailedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event",
                            "to",
                            "message_purpose",
                            "error"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.failed"
                                ]
                            },
                            "to": {
                                "type": "string",
                                "example": "+9665XXXXXXX"
                            },
                            "message_purpose": {
                                "type": "string"
                            },
                            "error": {
                                "type": "string",
                                "example": "Delivery could not be completed."
                            }
                        }
                    }
                ]
            },
            "RecipientOptedOutEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event",
                            "from",
                            "reason"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "recipient.opted_out"
                                ]
                            },
                            "from": {
                                "type": "string",
                                "example": "+9665XXXXXXX"
                            },
                            "reason": {
                                "type": "string",
                                "example": "recipient_requested_stop"
                            },
                            "message_text": {
                                "type": "string",
                                "example": "STOP"
                            }
                        }
                    }
                ]
            },
            "InstanceConnectedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "instance.connected"
                                ]
                            },
                            "connection_state": {
                                "type": "string",
                                "example": "connected"
                            }
                        }
                    }
                ]
            },
            "InstanceDisconnectedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "instance.disconnected"
                                ]
                            },
                            "connection_state": {
                                "type": "string",
                                "example": "connected"
                            }
                        }
                    }
                ]
            },
            "InstanceConnectionUpdatedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "instance.connection_updated"
                                ]
                            },
                            "connection_state": {
                                "type": "string",
                                "example": "connected"
                            }
                        }
                    }
                ]
            },
            "InstanceQrUpdatedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "instance.qr_updated"
                                ]
                            },
                            "qr_available": {
                                "type": "boolean",
                                "example": true
                            }
                        }
                    }
                ]
            },
            "MessageDeliveredEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.delivered"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "external_message_id": {
                                "type": "string"
                            },
                            "status": {
                                "type": "string",
                                "example": "delivered"
                            }
                        }
                    }
                ]
            },
            "MessageReadEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.read"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "external_message_id": {
                                "type": "string"
                            },
                            "status": {
                                "type": "string",
                                "example": "delivered"
                            }
                        }
                    }
                ]
            },
            "MessageStatusUpdatedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "message.status_updated"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "external_message_id": {
                                "type": "string"
                            },
                            "status": {
                                "type": "string",
                                "example": "delivered"
                            }
                        }
                    }
                ]
            },
            "ConversationUpdatedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "conversation.updated"
                                ]
                            },
                            "conversation_id": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "CallReceivedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "call.received"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "call_status": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "CallMissedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "call.missed"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "call_status": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "GroupMessageReceivedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event",
                            "group_id"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "group.message_received"
                                ]
                            },
                            "from": {
                                "type": "string"
                            },
                            "group_id": {
                                "type": "string"
                            },
                            "message_text": {
                                "type": "string"
                            },
                            "external_message_id": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "GroupUpdatedEvent": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/CustomerWebhookEventBase"
                    },
                    {
                        "type": "object",
                        "required": [
                            "event"
                        ],
                        "properties": {
                            "event": {
                                "type": "string",
                                "enum": [
                                    "group.updated"
                                ]
                            },
                            "group_id": {
                                "type": "string"
                            }
                        }
                    }
                ]
            },
            "ThreeCxWebhookRequest": {
                "type": "object",
                "required": [
                    "event_type"
                ],
                "properties": {
                    "event_type": {
                        "type": "string",
                        "enum": [
                            "test",
                            "outbound_message",
                            "inbound_reply",
                            "missed_call",
                            "call_started",
                            "call_ended",
                            "voicemail",
                            "queue_event",
                            "queue_callback",
                            "after_hours"
                        ]
                    },
                    "to": {
                        "type": "string",
                        "description": "Destination phone for outbound_message events."
                    },
                    "customer_phone": {
                        "type": "string",
                        "description": "Customer phone for call-event templates."
                    },
                    "message_text": {
                        "type": "string",
                        "description": "Message body for outbound_message events."
                    },
                    "message_purpose": {
                        "type": "string",
                        "enum": [
                            "support",
                            "operational",
                            "transactional",
                            "internal_team",
                            "authentication"
                        ]
                    },
                    "conversation_id": {
                        "type": "string"
                    },
                    "external_message_id": {
                        "type": "string"
                    },
                    "agent_extension": {
                        "type": "string"
                    },
                    "queue": {
                        "type": "string"
                    },
                    "call_time": {
                        "type": "string"
                    }
                }
            },
            "ThreeCxWebhookResponse": {
                "type": "object",
                "required": [
                    "success",
                    "status",
                    "event_type",
                    "action"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "status": {
                        "type": "string",
                        "example": "processed"
                    },
                    "event_type": {
                        "type": "string",
                        "example": "test"
                    },
                    "action": {
                        "type": "string",
                        "example": "received"
                    },
                    "message_id": {
                        "type": "string"
                    }
                }
            }
        },
        "headers": {
            "X-WhatsApp-Gateway-Event": {
                "description": "Normalized WhatsApp Gateway event name.",
                "schema": {
                    "type": "string"
                }
            },
            "X-WhatsApp-Gateway-Timestamp": {
                "description": "Unix timestamp used for webhook signature verification.",
                "schema": {
                    "type": "string"
                }
            },
            "X-WhatsApp-Gateway-Signature": {
                "description": "HMAC-SHA256 signature of timestamp + \".\" + raw_body.",
                "schema": {
                    "type": "string"
                }
            }
        }
    }
}