{
  "openapi": "3.1.0",
  "info": {
    "title": "WhaBuzz API",
    "version": "2026-10-16",
    "summary": "WhatsApp Cloud API gateway. Meta's bodies in, Meta's bodies out.",
    "description": "WhaBuzz connects your WhatsApp Business numbers to your server through Meta's Cloud API.\nRequest bodies for messages and templates are Meta's own; responses are Meta's own.\nWhaBuzz adds tenants, API keys, signed webhooks with retries and replay, and a searchable event log.\n\n**Errors** come from one of two sources, named in the body and in `X-WhaBuzz-Error-Source`:\n`whabuzz` (we stopped the request before or around Meta) or `meta` (Meta answered with an error,\npassed through with Meta's HTTP status, byte for byte).\n\n**Timing**: every response carries `Server-Timing: wb;dur=<our ms>, meta;dur=<Meta ms>` and\n`X-WhaBuzz-Processing-Ms`.\n\n**Authentication**: `Authorization: Bearer wb_live_…` (or `wb_test_…`). Platform (app) keys act on one\ntenant at a time with `X-WhaBuzz-Tenant: <tenant_id>`.\n\n**Pricing**: ₹500/month for your first number, ₹250 for each additional, ex-GST. You pay Meta's\nconversation rates to Meta. We never charge per message.\n",
    "contact": {
      "email": "support@whabuzz.com",
      "url": "https://docs.whabuzz.com"
    },
    "termsOfService": "https://whabuzz.com/legal/terms"
  },
  "servers": [
    {
      "url": "https://api.whabuzz.com"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Health",
      "description": "Liveness and database reachability."
    },
    {
      "name": "Tenant",
      "description": "The tenant your key belongs to."
    },
    {
      "name": "Tenants",
      "description": "Platform (app) keys only. Create and list the businesses you manage."
    },
    {
      "name": "API keys",
      "description": "Tenant API keys. The full key is shown once."
    },
    {
      "name": "Numbers",
      "description": "Connect and manage WhatsApp Business numbers. A number is `connected` only after the WABA is subscribed to WhaBuzz, the number is registered, and a webhook endpoint has passed its verify ping."
    },
    {
      "name": "Connect sessions",
      "description": "Hosted Embedded Signup links for your own customers."
    },
    {
      "name": "Messages",
      "description": "Send any message type Meta supports. The body is Meta's `/messages` body plus `from`."
    },
    {
      "name": "Media",
      "description": "Upload and download media. WhaBuzz proxies Meta and stores nothing."
    },
    {
      "name": "Templates",
      "description": "Meta message templates. Bodies and answers are Meta's."
    },
    {
      "name": "Webhooks",
      "description": "Endpoints, signing secrets, deliveries and replay."
    },
    {
      "name": "Events",
      "description": "The event log. Bodies are kept for your retention period (30/90/180/365 days); metadata longer."
    },
    {
      "name": "Billing",
      "description": "Flat monthly price per number. Never per message. Until billing is switched on, every /v1/billing route answers 503 billing_disabled (details.billing_enabled=false)."
    },
    {
      "name": "Admin",
      "description": "WhaBuzz staff only (platform admin console session)."
    }
  ],
  "paths": {
    "/v1/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "operationId": "getHealth",
        "security": [],
        "summary": "Service health",
        "responses": {
          "200": {
            "description": "Healthy",
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "sha": "a77affe",
                  "db": "ok"
                }
              }
            }
          },
          "503": {
            "description": "Database unreachable",
            "content": {
              "application/json": {
                "example": {
                  "ok": false,
                  "sha": "a77affe",
                  "db": "error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tenant": {
      "get": {
        "tags": [
          "Tenant"
        ],
        "operationId": "getTenant",
        "summary": "Current tenant, including the Getting-started checklist",
        "description": "Allowed for every tenant status, so a pending tenant can see why it is blocked.",
        "responses": {
          "200": {
            "description": "Tenant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                },
                "example": {
                  "id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
                  "name": "Acme Fitness",
                  "status": "active",
                  "sandbox": false,
                  "retention_days": 90,
                  "billing_status": "trialing",
                  "trial_ends_at": "2026-10-30T09:00:00Z",
                  "created_at": "2026-10-16T09:00:00Z",
                  "checklist": {
                    "number_connected": true,
                    "api_key_created": true,
                    "webhook_verified": false,
                    "test_message_sent": false
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "patch": {
        "tags": [
          "Tenant"
        ],
        "operationId": "updateTenant",
        "summary": "Update retention or billing email",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "retention_days": {
                    "type": "integer",
                    "enum": [
                      30,
                      90,
                      180,
                      365
                    ]
                  },
                  "billing_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "retention_days": 180
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated tenant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                },
                "example": {
                  "id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
                  "name": "Acme Fitness",
                  "status": "active",
                  "retention_days": 180
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/tenants": {
      "get": {
        "tags": [
          "Tenants"
        ],
        "operationId": "listTenants",
        "summary": "List tenants created by your app key",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "external_ref",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenants",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "7d0f3c1e-2b8a-4c55-9f61-0e9b1a2c3d4e",
                      "name": "Sunrise Clinic",
                      "external_ref": "org_4812",
                      "status": "active",
                      "created_at": "2026-10-16T10:00:00Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      },
      "post": {
        "tags": [
          "Tenants"
        ],
        "operationId": "createTenant",
        "summary": "Create a tenant for one of your customers",
        "description": "Tenants created with an app key are active immediately. Connect their number with a Connect session.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "external_ref": {
                    "type": "string",
                    "description": "Your own id for this business. Unique per app."
                  },
                  "retention_days": {
                    "type": "integer",
                    "enum": [
                      30,
                      90,
                      180,
                      365
                    ],
                    "default": 90
                  }
                }
              },
              "example": {
                "name": "Sunrise Clinic",
                "external_ref": "org_4812"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "example": {
                  "id": "7d0f3c1e-2b8a-4c55-9f61-0e9b1a2c3d4e",
                  "name": "Sunrise Clinic",
                  "external_ref": "org_4812",
                  "status": "active",
                  "retention_days": 90,
                  "created_at": "2026-10-16T10:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/tenants/{tenant_id}": {
      "get": {
        "tags": [
          "Tenants"
        ],
        "operationId": "getTenantById",
        "summary": "Get one of your app's tenants",
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant",
            "content": {
              "application/json": {
                "example": {
                  "id": "7d0f3c1e-2b8a-4c55-9f61-0e9b1a2c3d4e",
                  "name": "Sunrise Clinic",
                  "external_ref": "org_4812",
                  "status": "active"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/api-keys": {
      "get": {
        "tags": [
          "API keys"
        ],
        "operationId": "listApiKeys",
        "summary": "List API keys (prefix only)",
        "responses": {
          "200": {
            "description": "Keys",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
                      "name": "Production",
                      "environment": "live",
                      "prefix": "wb_live_7Hq2",
                      "created_at": "2026-10-16T09:10:00Z",
                      "last_used_at": "2026-10-16T09:40:00Z",
                      "expires_at": null,
                      "revoked_at": null
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "API keys"
        ],
        "operationId": "createApiKey",
        "summary": "Create an API key",
        "description": "The full key is in this response only. Store it now.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "default": "live"
                  }
                }
              },
              "example": {
                "name": "Production",
                "environment": "live"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "example": {
                  "id": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
                  "name": "Production",
                  "environment": "live",
                  "prefix": "wb_live_7Hq2",
                  "key": "wb_live_7Hq2Xc9LmN4pR8sT1vW6yZ0aB3dE5fG7hJ2kM4nP6",
                  "created_at": "2026-10-16T09:10:00Z"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/api-keys/{key_id}": {
      "delete": {
        "tags": [
          "API keys"
        ],
        "operationId": "revokeApiKey",
        "summary": "Revoke a key now",
        "description": "Takes effect within 30 seconds everywhere.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked",
            "content": {
              "application/json": {
                "example": {
                  "id": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
                  "revoked_at": "2026-10-16T11:00:00Z"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/api-keys/{key_id}/rotate": {
      "post": {
        "tags": [
          "API keys"
        ],
        "operationId": "rotateApiKey",
        "summary": "Rotate a key",
        "description": "Returns a new key. The old key keeps working for 24 hours, then expires.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "New key",
            "content": {
              "application/json": {
                "example": {
                  "id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a49382716",
                  "name": "Production",
                  "environment": "live",
                  "prefix": "wb_live_Qm3x",
                  "key": "wb_live_Qm3xV8bN1cK5zL7aS2dF4gH6jP9rT0wY3uE5iO7",
                  "replaces": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
                  "old_key_expires_at": "2026-10-17T11:00:00Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers": {
      "get": {
        "tags": [
          "Numbers"
        ],
        "operationId": "listNumbers",
        "summary": "List numbers",
        "responses": {
          "200": {
            "description": "Numbers",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "phone_number_id": "1013622581841046",
                      "display_phone_number": "+1 469-231-1132",
                      "verified_name": "WhaBuzz Demo",
                      "waba_id": "26059971920328384",
                      "connection_state": "connected",
                      "connection_detail": null,
                      "quality_rating": "GREEN",
                      "messaging_limit_tier": "TIER_250",
                      "throughput_level": "STANDARD"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}": {
      "get": {
        "tags": [
          "Numbers"
        ],
        "operationId": "getNumber",
        "summary": "Get a number",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          },
          {
            "name": "refresh",
            "in": "query",
            "description": "Re-read the number from Meta first (stored as `meta_snapshot`).",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Number"
                },
                "examples": {
                  "connected": {
                    "$ref": "#/components/examples/NumberConnected"
                  },
                  "pending": {
                    "value": {
                      "phone_number_id": "1013622581841046",
                      "display_phone_number": "+1 469-231-1132",
                      "waba_id": "26059971920328384",
                      "connection_state": "pending",
                      "connection_detail": "no_verified_endpoint"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/numbers/embedded-signup": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "completeEmbeddedSignup",
        "summary": "Finish Embedded Signup with the code from Meta's popup",
        "description": "Exchanges the code, checks the token, subscribes the WABA to WhaBuzz, registers the number and stores Meta's view of it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code",
                  "waba_id",
                  "phone_number_id"
                ],
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "waba_id": {
                    "type": "string"
                  },
                  "phone_number_id": {
                    "type": "string"
                  },
                  "pin": {
                    "type": "string",
                    "pattern": "^[0-9]{6}$",
                    "description": "Two-step PIN to register with. Generated when omitted."
                  }
                }
              },
              "example": {
                "code": "AQBx…",
                "waba_id": "26059971920328384",
                "phone_number_id": "1013622581841046"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Number stored. `connection_state` tells you what is left.",
            "content": {
              "application/json": {
                "example": {
                  "phone_number_id": "1013622581841046",
                  "display_phone_number": "+1 469-231-1132",
                  "waba_id": "26059971920328384",
                  "connection_state": "pending",
                  "connection_detail": "no_verified_endpoint"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/numbers/connect": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "connectExisting",
        "summary": "Connect an existing WABA with a business system-user token",
        "description": "For businesses that already have a WABA. The token must belong to WhaBuzz's Meta app\n(`debug_token` app id), carry `whatsapp_business_management` and `whatsapp_business_messaging`,\nand list `waba_id` in its granular scopes. WhaBuzz subscribes the WABA and imports its numbers.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "waba_id"
                ],
                "properties": {
                  "waba_id": {
                    "type": "string"
                  },
                  "access_token": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string",
                    "description": "Alternative to access_token: an Embedded Signup code."
                  }
                }
              },
              "example": {
                "waba_id": "1496378315413646",
                "access_token": "EAAG…"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Imported numbers",
            "content": {
              "application/json": {
                "example": {
                  "waba_id": "1496378315413646",
                  "numbers": [
                    {
                      "phone_number_id": "301234567890123",
                      "display_phone_number": "+91 95158 47444",
                      "connection_state": "pending",
                      "connection_detail": "not_registered"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Token checks failed, or Meta error",
            "content": {
              "application/json": {
                "examples": {
                  "whabuzz": {
                    "value": {
                      "source": "whabuzz",
                      "error": {
                        "code": "invalid_request",
                        "message": "Token is not scoped to WABA 1496378315413646",
                        "details": {
                          "granular_scopes": [
                            "whatsapp_business_messaging"
                          ]
                        }
                      },
                      "request_id": "req_01JAB3M0P4Q7R2S5T8V1W4X7Y0"
                    }
                  },
                  "meta": {
                    "$ref": "#/components/examples/MetaInvalidToken"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/migrate": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "migrateNumber",
        "summary": "Start migrating a number into one of your WABAs",
        "description": "Wraps `POST /{waba_id}/phone_numbers` with `migrate_phone_number=true`. Follow with request-code, verify-code and register.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "waba_id",
                  "cc",
                  "phone_number"
                ],
                "properties": {
                  "waba_id": {
                    "type": "string"
                  },
                  "cc": {
                    "type": "string"
                  },
                  "phone_number": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "waba_id": "1496378315413646",
                "cc": "91",
                "phone_number": "9515847444"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "id": "301234567890123"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/register": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "registerNumber",
        "summary": "Register the number with Cloud API",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pin": {
                    "type": "string",
                    "pattern": "^[0-9]{6}$"
                  }
                }
              },
              "example": {
                "pin": "482913"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/deregister": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "deregisterNumber",
        "summary": "Deregister the number",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/request-code": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "requestVerificationCode",
        "summary": "Request an SMS or voice verification code",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code_method",
                  "language"
                ],
                "properties": {
                  "code_method": {
                    "type": "string",
                    "enum": [
                      "SMS",
                      "VOICE"
                    ]
                  },
                  "language": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "code_method": "SMS",
                "language": "en_US"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/verify-code": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "verifyCode",
        "summary": "Verify the code",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "code": "123456"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/two-step": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "setTwoStepPin",
        "summary": "Set or change the two-step verification PIN",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pin"
                ],
                "properties": {
                  "pin": {
                    "type": "string",
                    "pattern": "^[0-9]{6}$"
                  }
                }
              },
              "example": {
                "pin": "482913"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/subscribe": {
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "resubscribeWaba",
        "summary": "Re-subscribe the number's WABA to WhaBuzz (repair)",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "responses": {
          "200": {
            "description": "Subscribed; connection state recomputed",
            "content": {
              "application/json": {
                "example": {
                  "phone_number_id": "1013622581841046",
                  "connection_state": "connected",
                  "connection_detail": null
                }
              }
            }
          }
        }
      }
    },
    "/v1/numbers/{phone_number_id}/business-profile": {
      "get": {
        "tags": [
          "Numbers"
        ],
        "operationId": "getBusinessProfile",
        "summary": "Get the WhatsApp business profile",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "about": "Strength coaching in Kokapet",
                      "address": "Kokapet, Hyderabad",
                      "description": "Personal training studio",
                      "email": "hello@example.com",
                      "messaging_product": "whatsapp",
                      "profile_picture_url": "https://pps.whatsapp.net/v/t61/…",
                      "websites": [
                        "https://example.com"
                      ],
                      "vertical": "HEALTH"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Numbers"
        ],
        "operationId": "updateBusinessProfile",
        "summary": "Update the WhatsApp business profile",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Meta's whatsapp_business_profile body."
              },
              "example": {
                "messaging_product": "whatsapp",
                "about": "Strength coaching in Kokapet",
                "websites": [
                  "https://example.com"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/connect-sessions": {
      "post": {
        "tags": [
          "Connect sessions"
        ],
        "operationId": "createConnectSession",
        "summary": "Create a hosted Embedded Signup link",
        "description": "Send your customer to `url`. After Meta's flow they return to `return_url?session_id=…&status=connected|failed`. Links expire after one hour.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "return_url"
                ],
                "properties": {
                  "return_url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "example": {
                "return_url": "https://app.example.com/settings/whatsapp"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session",
            "content": {
              "application/json": {
                "example": {
                  "id": "cs_01JAB3N2R5T8W1Y4A7C0E3G6J9",
                  "url": "https://app.whabuzz.com/connect/9fK2mQ7xL4pV1sN8cR3t",
                  "expires_at": "2026-10-16T11:00:00Z",
                  "status": "open"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connect-sessions/{session_id}": {
      "get": {
        "tags": [
          "Connect sessions"
        ],
        "operationId": "getConnectSession",
        "summary": "Get a Connect session",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session",
            "content": {
              "application/json": {
                "example": {
                  "id": "cs_01JAB3N2R5T8W1Y4A7C0E3G6J9",
                  "status": "connected",
                  "result": {
                    "waba_id": "26059971920328384",
                    "phone_number_ids": [
                      "1013622581841046"
                    ]
                  },
                  "expires_at": "2026-10-16T11:00:00Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "sendMessage",
        "summary": "Send a message",
        "description": "The body is Meta's `POST /{phone_number_id}/messages` body plus `from` (your number's\nphone_number_id or E.164). WhaBuzz adds nothing and checks nothing about content, category\nor the customer-service window. Meta decides; its answer comes back verbatim.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendRequest"
              },
              "examples": {
                "text": {
                  "summary": "Text",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "recipient_type": "individual",
                    "to": "16505551234",
                    "type": "text",
                    "text": {
                      "preview_url": false,
                      "body": "Your trial is booked for 7:00 AM tomorrow."
                    }
                  }
                },
                "template": {
                  "summary": "Template with body parameters",
                  "value": {
                    "from": "+14692311132",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "template",
                    "template": {
                      "name": "renewal_reminder",
                      "language": {
                        "code": "en"
                      },
                      "components": [
                        {
                          "type": "body",
                          "parameters": [
                            {
                              "type": "text",
                              "text": "Kerry"
                            },
                            {
                              "type": "text",
                              "text": "31 Oct"
                            }
                          ]
                        }
                      ]
                    }
                  }
                },
                "template_auth": {
                  "summary": "Authentication template (you send the copy-code button yourself)",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "template",
                    "template": {
                      "name": "login_code",
                      "language": {
                        "code": "en_US"
                      },
                      "components": [
                        {
                          "type": "body",
                          "parameters": [
                            {
                              "type": "text",
                              "text": "482913"
                            }
                          ]
                        },
                        {
                          "type": "button",
                          "sub_type": "url",
                          "index": "0",
                          "parameters": [
                            {
                              "type": "text",
                              "text": "482913"
                            }
                          ]
                        }
                      ]
                    }
                  }
                },
                "image": {
                  "summary": "Image by media id",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "image",
                    "image": {
                      "id": "1479537139650973",
                      "caption": "This week's timetable"
                    }
                  }
                },
                "document_link": {
                  "summary": "Document by link",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "document",
                    "document": {
                      "link": "https://example.com/invoice-1042.pdf",
                      "filename": "invoice-1042.pdf"
                    }
                  }
                },
                "interactive_buttons": {
                  "summary": "Reply buttons",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "body": {
                        "text": "Confirm your 7:00 AM session?"
                      },
                      "action": {
                        "buttons": [
                          {
                            "type": "reply",
                            "reply": {
                              "id": "confirm_yes",
                              "title": "Yes"
                            }
                          },
                          {
                            "type": "reply",
                            "reply": {
                              "id": "confirm_no",
                              "title": "Reschedule"
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "interactive_list": {
                  "summary": "List",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "interactive",
                    "interactive": {
                      "type": "list",
                      "body": {
                        "text": "Pick a slot"
                      },
                      "action": {
                        "button": "Slots",
                        "sections": [
                          {
                            "title": "Tomorrow",
                            "rows": [
                              {
                                "id": "slot_0700",
                                "title": "7:00 AM",
                                "description": "Strength"
                              },
                              {
                                "id": "slot_1800",
                                "title": "6:00 PM",
                                "description": "Conditioning"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                },
                "location": {
                  "summary": "Location",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "location",
                    "location": {
                      "latitude": 17.3953,
                      "longitude": 78.3363,
                      "name": "Studio",
                      "address": "Kokapet, Hyderabad"
                    }
                  }
                },
                "reaction": {
                  "summary": "Reaction",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "reaction",
                    "reaction": {
                      "message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA",
                      "emoji": "👍"
                    }
                  }
                },
                "reply": {
                  "summary": "Reply in thread (context)",
                  "value": {
                    "from": "1013622581841046",
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "context": {
                      "message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA"
                    },
                    "type": "text",
                    "text": {
                      "body": "See you at 7."
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta accepted the message. Body is Meta's, verbatim.",
            "headers": {
              "X-WhaBuzz-Event-Id": {
                "$ref": "#/components/headers/EventId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              },
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present when this is a stored response for a repeated Idempotency-Key."
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "messaging_product": "whatsapp",
                  "contacts": [
                    {
                      "input": "16505551234",
                      "wa_id": "16505551234"
                    }
                  ],
                  "messages": [
                    {
                      "id": "wamid.HBgLMTY1MDU1NTEyMzQVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA",
                      "message_status": "accepted"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Meta rejected the request (any Meta 4xx is passed through with its own status), or WhaBuzz rejected the body.",
            "content": {
              "application/json": {
                "examples": {
                  "meta_not_allowed": {
                    "$ref": "#/components/examples/MetaNotAllowed"
                  },
                  "meta_template_params": {
                    "$ref": "#/components/examples/MetaTemplateParams"
                  },
                  "whabuzz_missing_from": {
                    "value": {
                      "source": "whabuzz",
                      "error": {
                        "code": "invalid_request",
                        "message": "`from` is required: a phone_number_id or E.164 number of this tenant",
                        "details": null
                      },
                      "request_id": "req_01JAB3P5S8V1X4Z7B0D3F6H9K2"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TenantBlocked"
          },
          "409": {
            "description": "Number not connected, or the same Idempotency-Key is still in flight.",
            "content": {
              "application/json": {
                "examples": {
                  "not_connected": {
                    "value": {
                      "source": "whabuzz",
                      "error": {
                        "code": "number_not_connected",
                        "message": "Number 1013622581841046 is not connected: no_verified_endpoint",
                        "details": {
                          "connection_detail": "no_verified_endpoint"
                        }
                      },
                      "request_id": "req_01JAB3Q6T9W2Y5A8C1E4G7J0M3"
                    }
                  },
                  "in_flight": {
                    "value": {
                      "source": "whabuzz",
                      "error": {
                        "code": "idempotency_conflict",
                        "message": "A request with this Idempotency-Key is still in progress",
                        "details": null
                      },
                      "request_id": "req_01JAB3R7V0X3Z6B9D2F5H8K1N4"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Idempotency-Key reused with a different body",
            "content": {
              "application/json": {
                "example": {
                  "source": "whabuzz",
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "Idempotency-Key was used with a different body",
                    "details": null
                  },
                  "request_id": "req_01JAB3S8W1Y4A7C0E3G6J9M2P5"
                }
              }
            }
          },
          "429": {
            "description": "Meta throttled the send (passed through)",
            "content": {
              "application/json": {
                "example": {
                  "source": "meta",
                  "error": {
                    "message": "(#130429) Rate limit hit",
                    "type": "OAuthException",
                    "code": 130429,
                    "error_data": {
                      "messaging_product": "whatsapp",
                      "details": "Cloud API message throughput has been reached."
                    },
                    "fbtrace_id": "AbCdEf1234567890"
                  }
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/MetaUnreachable"
          }
        }
      }
    },
    "/v1/messages/read": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "markRead",
        "summary": "Mark an inbound message read, optionally showing a typing indicator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "from",
                  "message_id"
                ],
                "properties": {
                  "from": {
                    "type": "string"
                  },
                  "message_id": {
                    "type": "string"
                  },
                  "typing_indicator": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "text"
                        ]
                      }
                    }
                  }
                }
              },
              "example": {
                "from": "1013622581841046",
                "message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA",
                "typing_indicator": {
                  "type": "text"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/messages/batch": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "createBatch",
        "summary": "Send many messages from one number",
        "description": "Up to 10,000 Meta message bodies. WhaBuzz paces them to the number's throughput and records\nMeta's answer for each, verbatim. Each item also produces a `message.outbound` event, and\nthe batch ends with `batch.completed`. WhaBuzz does not retry items Meta rejected.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "from",
                  "messages"
                ],
                "properties": {
                  "from": {
                    "type": "string"
                  },
                  "client_ref": {
                    "type": "string",
                    "description": "Your reference. Unique per tenant; a repeat returns the existing batch."
                  },
                  "messages": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10000,
                    "items": {
                      "type": "object",
                      "description": "Meta /messages body without `from`."
                    }
                  }
                }
              },
              "example": {
                "from": "1013622581841046",
                "client_ref": "renewals-2026-11",
                "messages": [
                  {
                    "messaging_product": "whatsapp",
                    "to": "16505551234",
                    "type": "template",
                    "template": {
                      "name": "renewal_reminder",
                      "language": {
                        "code": "en"
                      },
                      "components": [
                        {
                          "type": "body",
                          "parameters": [
                            {
                              "type": "text",
                              "text": "Kerry"
                            },
                            {
                              "type": "text",
                              "text": "31 Oct"
                            }
                          ]
                        }
                      ]
                    }
                  },
                  {
                    "messaging_product": "whatsapp",
                    "to": "16505551235",
                    "type": "template",
                    "template": {
                      "name": "renewal_reminder",
                      "language": {
                        "code": "en"
                      },
                      "components": [
                        {
                          "type": "body",
                          "parameters": [
                            {
                              "type": "text",
                              "text": "Ravi"
                            },
                            {
                              "type": "text",
                              "text": "2 Nov"
                            }
                          ]
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued",
            "content": {
              "application/json": {
                "example": {
                  "id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
                  "status": "queued",
                  "total": 2,
                  "accepted": 0,
                  "failed": 0,
                  "rate_per_sec": 20,
                  "client_ref": "renewals-2026-11",
                  "created_at": "2026-10-16T10:00:00Z"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/NotConnected"
          }
        }
      }
    },
    "/v1/messages/batch/{batch_id}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "operationId": "getBatch",
        "summary": "Batch progress",
        "parameters": [
          {
            "$ref": "#/components/parameters/BatchId"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch",
            "content": {
              "application/json": {
                "example": {
                  "id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
                  "status": "completed",
                  "total": 2,
                  "accepted": 1,
                  "failed": 1,
                  "started_at": "2026-10-16T10:01:00Z",
                  "completed_at": "2026-10-16T10:01:01Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages/batch/{batch_id}/items": {
      "get": {
        "tags": [
          "Messages"
        ],
        "operationId": "listBatchItems",
        "summary": "Batch items with Meta's response for each",
        "parameters": [
          {
            "$ref": "#/components/parameters/BatchId"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "accepted",
                "failed",
                "skipped"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Items",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "idx": 1,
                      "status": "failed",
                      "http_status": 400,
                      "wamid": null,
                      "response": {
                        "error": {
                          "message": "(#131030) Recipient phone number not in allowed list",
                          "type": "OAuthException",
                          "code": 131030,
                          "error_data": {
                            "messaging_product": "whatsapp",
                            "details": "Recipient phone number not in allowed list: Add recipient phone number to recipient list and try again."
                          },
                          "fbtrace_id": "A1b2C3d4E5f6G7h8"
                        }
                      },
                      "event_id": "evt_01JAB3V0Y3A6C9E2G5J8M1P4R7",
                      "sent_at": "2026-10-16T10:01:01Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages/batch/{batch_id}/cancel": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "cancelBatch",
        "summary": "Cancel the unsent part of a batch",
        "parameters": [
          {
            "$ref": "#/components/parameters/BatchId"
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "example": {
                  "id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
                  "status": "cancelled",
                  "total": 2000,
                  "accepted": 640,
                  "failed": 3
                }
              }
            }
          }
        }
      }
    },
    "/v1/media": {
      "post": {
        "tags": [
          "Media"
        ],
        "operationId": "uploadMedia",
        "summary": "Upload media to Meta for sending",
        "description": "Stored by Meta, not by WhaBuzz.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "type",
                  "from"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "type": {
                    "type": "string",
                    "example": "image/jpeg"
                  },
                  "from": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "id": "1479537139650973"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/MetaError"
          }
        }
      }
    },
    "/v1/media/{media_id}": {
      "get": {
        "tags": [
          "Media"
        ],
        "operationId": "downloadMedia",
        "summary": "Download inbound media",
        "description": "Streams the bytes from Meta. WhaBuzz never stores media. Meta keeps inbound media for a limited time; download promptly.",
        "parameters": [
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Number that received it; needed only when the tenant has several WABAs.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "Meta does not know this media id (passed through)",
            "content": {
              "application/json": {
                "example": {
                  "source": "meta",
                  "error": {
                    "message": "Unsupported get request. Object with ID '1479537139650973' does not exist, cannot be loaded due to missing permissions, or does not support this operation.",
                    "type": "GraphMethodException",
                    "code": 100,
                    "error_subcode": 33,
                    "fbtrace_id": "AxYz0123456789"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Media"
        ],
        "operationId": "deleteMedia",
        "summary": "Delete uploaded media from Meta",
        "parameters": [
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/templates": {
      "get": {
        "tags": [
          "Templates"
        ],
        "operationId": "listTemplates",
        "summary": "List templates",
        "parameters": [
          {
            "name": "waba_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "APPROVED",
                "PENDING",
                "REJECTED",
                "PAUSED",
                "DISABLED"
              ]
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "1689556908129833",
                      "waba_id": "26059971920328384",
                      "name": "diwali_offer",
                      "language": "en",
                      "category": "MARKETING",
                      "status": "REJECTED",
                      "status_reason": "INVALID_FORMAT: Template body contains variables at the start or end.",
                      "quality_score": null,
                      "parameter_format": "POSITIONAL",
                      "meta_object": {
                        "id": "1689556908129833",
                        "name": "diwali_offer",
                        "language": "en",
                        "status": "REJECTED",
                        "category": "MARKETING",
                        "components": [
                          {
                            "type": "BODY",
                            "text": "{{1}} off this Diwali"
                          }
                        ]
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Templates"
        ],
        "operationId": "createTemplate",
        "summary": "Submit a template to Meta",
        "description": "Body is Meta's `POST /{waba_id}/message_templates` body plus `waba_id`. Response is Meta's.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "language",
                  "category",
                  "components"
                ]
              },
              "example": {
                "waba_id": "26059971920328384",
                "name": "renewal_reminder",
                "language": "en",
                "category": "UTILITY",
                "parameter_format": "POSITIONAL",
                "components": [
                  {
                    "type": "BODY",
                    "text": "Hi {{1}}, your membership renews on {{2}}.",
                    "example": {
                      "body_text": [
                        [
                          "Kerry",
                          "31 Oct"
                        ]
                      ]
                    }
                  },
                  {
                    "type": "BUTTONS",
                    "buttons": [
                      {
                        "type": "QUICK_REPLY",
                        "text": "Renew now"
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "id": "1689556908129832",
                  "status": "PENDING",
                  "category": "UTILITY"
                }
              }
            }
          },
          "400": {
            "description": "Meta rejected the template",
            "content": {
              "application/json": {
                "example": {
                  "source": "meta",
                  "error": {
                    "message": "Invalid parameter",
                    "type": "OAuthException",
                    "code": 100,
                    "error_subcode": 2388023,
                    "is_transient": false,
                    "error_user_title": "Message template language is being deleted",
                    "error_user_msg": "New en content can't be added while the existing en content is being deleted. Try again in 4 weeks or consider creating a new message template.",
                    "fbtrace_id": "AqXyZ123"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/templates/{template_id}": {
      "get": {
        "tags": [
          "Templates"
        ],
        "operationId": "getTemplate",
        "summary": "Get a template",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template",
            "content": {
              "application/json": {
                "example": {
                  "id": "1689556908129832",
                  "name": "renewal_reminder",
                  "language": "en",
                  "category": "UTILITY",
                  "status": "APPROVED",
                  "quality_score": "GREEN",
                  "meta_object": {
                    "id": "1689556908129832",
                    "status": "APPROVED"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Templates"
        ],
        "operationId": "editTemplate",
        "summary": "Edit a template",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "components": [
                  {
                    "type": "BODY",
                    "text": "Hi {{1}}, your plan renews on {{2}}.",
                    "example": {
                      "body_text": [
                        [
                          "Kerry",
                          "31 Oct"
                        ]
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Templates"
        ],
        "operationId": "deleteTemplate",
        "summary": "Delete a template",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "success": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/templates/sync": {
      "post": {
        "tags": [
          "Templates"
        ],
        "operationId": "syncTemplates",
        "summary": "Re-read every template from Meta",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "waba_id": "26059971920328384"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Counts",
            "content": {
              "application/json": {
                "example": {
                  "waba_id": "26059971920328384",
                  "fetched": 10,
                  "inserted": 0,
                  "updated": 2
                }
              }
            }
          }
        }
      }
    },
    "/v1/templates/library": {
      "get": {
        "tags": [
          "Templates"
        ],
        "operationId": "listTemplateLibrary",
        "summary": "Browse Meta's template library",
        "description": "Query parameters are passed to Meta unchanged.",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "topic",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "name": "appointment_reminder_1",
                      "language": "en_US",
                      "category": "UTILITY",
                      "topic": "APPOINTMENTS",
                      "body": "This is a reminder of your upcoming appointment on {{1}} at {{2}}."
                    }
                  ],
                  "paging": {
                    "cursors": {
                      "before": "QVFI",
                      "after": "QVFJ"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/templates/media-handle": {
      "post": {
        "tags": [
          "Templates"
        ],
        "operationId": "createTemplateMediaHandle",
        "summary": "Upload a header sample and get a handle for template creation",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Meta's response verbatim",
            "content": {
              "application/json": {
                "example": {
                  "h": "4::aW1hZ2UvanBlZw==:ARZ…"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookEndpoints",
        "summary": "List endpoints",
        "responses": {
          "200": {
            "description": "Endpoints",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                      "url": "https://api.example.com/whatsapp/events",
                      "event_types": [
                        "*"
                      ],
                      "status": "active",
                      "verified_at": "2026-10-16T09:20:00Z",
                      "secret_prefix": "whsec_Zm9v",
                      "consecutive_failures": 0
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhookEndpoint",
        "summary": "Add an endpoint",
        "description": "WhaBuzz sends a verify ping right away. Your endpoint must answer 2xx with the `challenge`\n(plain text, or JSON `{\"challenge\":\"…\"}`). Until an endpoint passes, your numbers are not\n`connected`. The signing secret is in this response only.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": {
                    "type": "string"
                  },
                  "event_types": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EventType"
                    },
                    "default": [
                      "*"
                    ]
                  }
                }
              },
              "example": {
                "url": "https://api.example.com/whatsapp/events",
                "event_types": [
                  "*"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created and verified",
            "content": {
              "application/json": {
                "example": {
                  "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                  "url": "https://api.example.com/whatsapp/events",
                  "event_types": [
                    "*"
                  ],
                  "status": "active",
                  "verified_at": "2026-10-16T09:20:00Z",
                  "secret": "whsec_Zm9vYmFyYmF6cXV4MTIzNDU2Nzg5MGFiY2RlZg",
                  "secret_prefix": "whsec_Zm9v"
                }
              }
            }
          },
          "422": {
            "description": "Created, but the verify ping failed. The endpoint stays pending; fix it and call verify.",
            "content": {
              "application/json": {
                "example": {
                  "source": "whabuzz",
                  "error": {
                    "code": "webhook_verify_failed",
                    "message": "Endpoint answered 200 without the challenge",
                    "details": {
                      "endpoint_id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                      "http_status": 200,
                      "body_excerpt": "OK",
                      "secret": "whsec_Zm9vYmFyYmF6cXV4MTIzNDU2Nzg5MGFiY2RlZg"
                    }
                  },
                  "request_id": "req_01JAB3W1Z4B7D0F3H6K9N2Q5S8"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhookEndpoint",
        "summary": "Get an endpoint",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                },
                "examples": {
                  "active": {
                    "$ref": "#/components/examples/EndpointActive"
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "updateWebhookEndpoint",
        "summary": "Change URL, event types, description or status",
        "description": "Changing `url` re-runs the verify ping.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "event_types": [
                  "message.inbound",
                  "message.status"
                ],
                "status": "active"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "example": {
                  "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                  "event_types": [
                    "message.inbound",
                    "message.status"
                  ],
                  "status": "active"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteWebhookEndpoint",
        "summary": "Delete an endpoint",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "example": {
                  "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                  "deleted": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/verify": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "verifyWebhookEndpoint",
        "summary": "Send the verify ping again",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "responses": {
          "200": {
            "description": "Passed",
            "content": {
              "application/json": {
                "example": {
                  "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                  "status": "active",
                  "verified_at": "2026-10-16T09:25:00Z",
                  "response_ms": 84
                }
              }
            }
          },
          "422": {
            "description": "Failed",
            "content": {
              "application/json": {
                "example": {
                  "source": "whabuzz",
                  "error": {
                    "code": "webhook_verify_failed",
                    "message": "Endpoint timed out after 5000 ms",
                    "details": {
                      "http_status": null
                    }
                  },
                  "request_id": "req_01JAB3X2A5C8E1G4J7M0P3S6U9"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "rotateWebhookSecret",
        "summary": "Rotate the signing secret",
        "description": "Both secrets sign every delivery until `previous_secret_expires_at`, so you can deploy the new one without dropping events.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "overlap_hours": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 168,
                    "default": 24
                  }
                }
              },
              "example": {
                "overlap_hours": 24
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New secret (shown once)",
            "content": {
              "application/json": {
                "example": {
                  "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                  "secret": "whsec_bmV3c2VjcmV0MTIzNDU2Nzg5MGFiY2RlZmdoaQ",
                  "secret_prefix": "whsec_bmV3",
                  "previous_secret_expires_at": "2026-10-17T09:30:00Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/replay": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "bulkReplay",
        "summary": "Re-send deliveries in a time range",
        "parameters": [
          {
            "$ref": "#/components/parameters/EndpointId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "from",
                  "to"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "to": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "status": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "delivered",
                        "failed",
                        "dead"
                      ]
                    },
                    "default": [
                      "failed",
                      "dead"
                    ]
                  },
                  "event_types": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EventType"
                    }
                  }
                }
              },
              "example": {
                "from": "2026-10-16T00:00:00Z",
                "to": "2026-10-16T06:00:00Z",
                "status": [
                  "dead"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued",
            "content": {
              "application/json": {
                "example": {
                  "queued": 312
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listDeliveries",
        "summary": "List deliveries",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed",
                "dead"
              ]
            }
          },
          {
            "name": "event_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "dlv_01JAB3Y3B6D9F2H5K8N1Q4T7W0",
                      "event_id": "evt_01JAB3K9X2S8C4M7Q1V5R6T0YZ",
                      "event_type": "message.inbound",
                      "endpoint_id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                      "status": "failed",
                      "attempts": 3,
                      "last_http_status": 503,
                      "next_attempt_at": "2026-10-16T05:15:03Z"
                    }
                  ],
                  "next_cursor": "dlv_01JAB3Y3B6D9F2H5K8N1Q4T7W0"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-deliveries/{delivery_id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "getDelivery",
        "summary": "Get a delivery with its attempt log",
        "parameters": [
          {
            "$ref": "#/components/parameters/DeliveryId"
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery",
            "content": {
              "application/json": {
                "examples": {
                  "failed": {
                    "$ref": "#/components/examples/DeliveryFailed"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-deliveries/{delivery_id}/replay": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "replayDelivery",
        "summary": "Re-send one delivery now",
        "description": "One synchronous attempt with today's secrets. Works within your retention window.",
        "parameters": [
          {
            "$ref": "#/components/parameters/DeliveryId"
          }
        ],
        "responses": {
          "200": {
            "description": "The new delivery",
            "content": {
              "application/json": {
                "example": {
                  "id": "dlv_01JAB3Z4C7E0G3J6M9P2S5V8Y1",
                  "status": "delivered",
                  "attempts": 1,
                  "last_http_status": 200,
                  "last_response_ms": 92,
                  "is_replay": true,
                  "replay_of": "dlv_01JAB3Y3B6D9F2H5K8N1Q4T7W0"
                }
              }
            }
          },
          "404": {
            "description": "Unknown delivery, or the event body is past retention",
            "content": {
              "application/json": {
                "example": {
                  "source": "whabuzz",
                  "error": {
                    "code": "not_found",
                    "message": "Event body expired under the tenant's 90-day retention",
                    "details": {
                      "reason": "payload_expired"
                    }
                  },
                  "request_id": "req_01JAB40A5D8F1H4K7N0Q3T6W9Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "operationId": "listEvents",
        "summary": "Search the event log",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EventType"
            }
          },
          {
            "name": "phone_number_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wamid",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wa_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error_code",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Event metadata, newest first",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "evt_01JAB3K9X2S8C4M7Q1V5R6T0YZ",
                      "type": "message.status",
                      "created_at": "2026-10-16T05:12:03.481Z",
                      "phone_number_id": "1013622581841046",
                      "wamid": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBNDMAAA=",
                      "wa_id": "16505551234",
                      "status": "failed",
                      "error_codes": [
                        131049
                      ]
                    }
                  ],
                  "next_cursor": "evt_01JAB3J8W1R7B3L6P0U4Q5S9XY"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{event_id}": {
      "get": {
        "tags": [
          "Events"
        ],
        "operationId": "getEvent",
        "summary": "Get one event with its full envelope and deliveries",
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event. `envelope` is null once the body is past retention.",
            "content": {
              "application/json": {
                "example": {
                  "id": "evt_01JAB3K9X2S8C4M7Q1V5R6T0YZ",
                  "type": "message.inbound",
                  "created_at": "2026-10-16T05:12:03.481Z",
                  "envelope": {
                    "note": "Same shape as the message.inbound webhook example (components.examples.EnvelopeInbound)"
                  },
                  "deliveries": [
                    {
                      "id": "dlv_01JAB3K9X3T9D5N8R2W6S7U1Z0",
                      "endpoint_id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                      "status": "delivered",
                      "attempts": 1,
                      "last_http_status": 200
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing": {
      "get": {
        "tags": [
          "Billing"
        ],
        "operationId": "getBilling",
        "summary": "Plan, active numbers and next charge",
        "responses": {
          "200": {
            "description": "Billing summary",
            "content": {
              "application/json": {
                "example": {
                  "plan": "₹500/month first number + ₹250/month each additional, ex-GST",
                  "billing_status": "trialing",
                  "trial_ends_at": "2026-10-30T09:00:00Z",
                  "active_numbers": 2,
                  "next_charge": {
                    "period": "2026-11-01",
                    "amount_paise": 75000,
                    "gst_paise": 13500,
                    "total_paise": 88500,
                    "charge_on": "2026-11-03"
                  },
                  "mandate": {
                    "status": "not_set_up"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/mandate": {
      "post": {
        "tags": [
          "Billing"
        ],
        "operationId": "createMandate",
        "summary": "Set up autopay",
        "description": "Returns Cashfree's authorisation link. Open it, approve the mandate (UPI Autopay, eNACH or card), and WhaBuzz charges the monthly total on the 3rd.",
        "responses": {
          "201": {
            "description": "Authorisation link",
            "content": {
              "application/json": {
                "example": {
                  "subscription_id": "wb_sub_a578246e",
                  "authorization_url": "https://sandbox.cashfree.com/pg/view/subscription/…",
                  "max_amount_paise": 200000
                }
              }
            }
          },
          "503": {
            "description": "Billing not enabled yet",
            "content": {
              "application/json": {
                "example": {
                  "source": "whabuzz",
                  "error": {
                    "code": "billing_disabled",
                    "message": "Billing is not enabled yet",
                    "details": {
                      "billing_enabled": false
                    }
                  },
                  "request_id": "req_01JAB41B6E9G2J5M8P1S4V7Y0B"
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/invoices": {
      "get": {
        "tags": [
          "Billing"
        ],
        "operationId": "listInvoices",
        "summary": "Invoices",
        "responses": {
          "200": {
            "description": "Invoices",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
                      "number": "WB/2026-27/000001",
                      "period": "2026-11-01",
                      "amount_paise": 75000,
                      "gst_paise": 13500,
                      "total_paise": 88500,
                      "status": "paid",
                      "paid_at": "2026-11-03T04:00:00Z",
                      "html_url": "https://api.whabuzz.com/v1/billing/invoices/9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/invoices/{invoice_id}": {
      "get": {
        "tags": [
          "Billing"
        ],
        "operationId": "getInvoice",
        "summary": "Printable invoice (HTML) or JSON with Accept application/json",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "example": {
                  "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
                  "number": "WB/2026-27/000001",
                  "line_items": [
                    {
                      "description": "WhatsApp number, first",
                      "quantity": 1,
                      "unit_paise": 50000,
                      "amount_paise": 50000
                    },
                    {
                      "description": "WhatsApp number, additional",
                      "quantity": 1,
                      "unit_paise": 25000,
                      "amount_paise": 25000
                    }
                  ],
                  "amount_paise": 75000,
                  "gst_paise": 13500,
                  "total_paise": 88500,
                  "status": "issued"
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/invoices/{invoice_id}/pay": {
      "post": {
        "tags": [
          "Billing"
        ],
        "operationId": "payInvoice",
        "summary": "Pay a failed invoice now",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Cashfree checkout link",
            "content": {
              "application/json": {
                "example": {
                  "payment_url": "https://sandbox.cashfree.com/pg/view/order/…"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/tenants": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminListTenants",
        "summary": "All tenants (approval queue with status=pending_approval)",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending_approval",
                "active",
                "rejected",
                "suspended"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Tenants",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                      "name": "Acme Fitness",
                      "status": "pending_approval",
                      "created_via": "signup",
                      "contact_email": "owner@acmefitness.in",
                      "website": "https://acmefitness.in",
                      "tax_id": "36ABCDE1234F1Z5",
                      "tax_id_type": "gstin",
                      "email_domain": "acmefitness.in",
                      "flags": [],
                      "created_at": "2026-10-16T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/admin/tenants/{tenant_id}/approve": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminApproveTenant",
        "summary": "Approve a tenant",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AdminTenantId"
          }
        ],
        "responses": {
          "200": {
            "description": "Approved",
            "content": {
              "application/json": {
                "example": {
                  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                  "status": "active",
                  "approved_at": "2026-10-16T09:00:00Z",
                  "billing_status": "trialing",
                  "trial_ends_at": "2026-10-30T09:00:00Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/tenants/{tenant_id}/reject": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminRejectTenant",
        "summary": "Reject a tenant",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AdminTenantId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "reason": "Website does not match the business name."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected",
            "content": {
              "application/json": {
                "example": {
                  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                  "status": "rejected",
                  "rejected_reason": "Website does not match the business name."
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/tenants/{tenant_id}/suspend": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminSuspendTenant",
        "summary": "Suspend a tenant",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AdminTenantId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string",
                    "enum": [
                      "abuse",
                      "admin"
                    ]
                  },
                  "note": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "reason": "abuse",
                "note": "Spam reports from Meta quality alerts"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Suspended",
            "content": {
              "application/json": {
                "example": {
                  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                  "status": "suspended",
                  "suspended_reason": "abuse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/tenants/{tenant_id}/reinstate": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminReinstateTenant",
        "summary": "Reinstate a suspended tenant",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AdminTenantId"
          }
        ],
        "responses": {
          "200": {
            "description": "Active again",
            "content": {
              "application/json": {
                "example": {
                  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                  "status": "active"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/numbers": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminListNumbers",
        "summary": "Every number across tenants",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "name": "connection_state",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "connected",
                "disconnected"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Numbers",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
                      "tenant_name": "WhaBuzz Demo",
                      "phone_number_id": "1013622581841046",
                      "display_phone_number": "+1 469-231-1132",
                      "connection_state": "connected",
                      "quality_rating": "GREEN",
                      "messaging_limit_tier": "TIER_250",
                      "last_event_at": "2026-10-16T05:12:03Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/health": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminHealth",
        "summary": "Pipeline health",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Health",
            "content": {
              "application/json": {
                "example": {
                  "retries_due": 4,
                  "oldest_due_retry_at": "2026-10-16T09:58:00Z",
                  "dead_24h": 0,
                  "endpoints_circuit_open": 1,
                  "tokens": {
                    "expiring": 0,
                    "invalid": 0
                  },
                  "partitions_through": {
                    "events": "2027-04",
                    "event_payloads": "2027-04",
                    "webhook_deliveries": "2027-04"
                  },
                  "kv_reconcile": {
                    "last_run_at": "2026-10-16T10:00:00Z",
                    "keys_rewritten": 0
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/audit": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminAudit",
        "summary": "Audit log",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "action",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Entries",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": 4012,
                      "tenant_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                      "actor_user_id": "6b5a4938-2716-4a5b-8c7d-9e0f1a2b3c4d",
                      "action": "tenant.approve",
                      "target_type": "tenant",
                      "target_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                      "details": {},
                      "created_at": "2026-10-16T09:00:00Z"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/billing": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminBilling",
        "summary": "Billing across tenants",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Billing",
            "content": {
              "application/json": {
                "example": {
                  "billing_enabled": false,
                  "tenants": [
                    {
                      "tenant_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                      "name": "Acme Fitness",
                      "billing_status": "past_due",
                      "past_due_since": "2026-11-03T04:00:00Z",
                      "last_snapshot": {
                        "period": "2026-11-01",
                        "active_numbers": 2,
                        "total_paise": 88500
                      },
                      "open_invoices": 1
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/mail/last": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminLastMail",
        "summary": "Last email sent to an address (EMAIL_MODE=log only)",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "name": "email",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "email"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The captured email",
            "content": {
              "application/json": {
                "example": {
                  "to": "owner@acmefitness.in",
                  "subject": "Confirm your WhaBuzz email",
                  "links": [
                    "https://app.whabuzz.com/verify-email?token=Qm9…"
                  ],
                  "sent_at": "2026-10-16T08:00:05Z"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/admin/apps": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminListApps",
        "summary": "Platform apps",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Apps",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "3e53b65e-0000-4000-8000-000000000001",
                      "name": "fisique-crm",
                      "tenants": 1
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminCreateApp",
        "summary": "Create a platform app",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "pariq"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "example": {
                  "id": "6f1e2d3c-4b5a-4697-8a8b-9c0d1e2f3a4b",
                  "name": "pariq"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/apps/{app_id}/keys": {
      "post": {
        "tags": [
          "Admin"
        ],
        "operationId": "adminCreateAppKey",
        "summary": "Create an app (platform) API key",
        "security": [
          {
            "consoleSession": []
          }
        ],
        "parameters": [
          {
            "name": "app_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "Pariq production",
                "environment": "live"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key, shown once",
            "content": {
              "application/json": {
                "example": {
                  "id": "2a3b4c5d-6e7f-4809-9a1b-2c3d4e5f6a7b",
                  "app_id": "6f1e2d3c-4b5a-4697-8a8b-9c0d1e2f3a4b",
                  "prefix": "wb_live_Pa7r",
                  "key": "wb_live_Pa7rQ2xN8mK4vB1cZ6lS9dF3gH5jT0wY7uE2iO4"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "event": {
      "post": {
        "summary": "Event delivery to your endpoint",
        "description": "One event per request, signed. Answer 2xx within 3 seconds; do the work afterwards.\nAnything else is retried: 30s, 1m, 2m, 5m, 10m, 20m, 40m, 1h, then hourly until 24 hours after\nthe first attempt, then the delivery is marked dead (replayable from the console or API).\nDeliveries can repeat and arrive out of order: dedupe on `dedupe_key`, order by Meta's timestamps.\n\nVerify: split `X-WhaBuzz-Signature` into `t` and one or more `v1`. Compute\nhex(HMAC-SHA256(secret, t + \".\" + raw_body)). Accept when any `v1` matches and t is within 300 s.\n",
        "parameters": [
          {
            "name": "X-WhaBuzz-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "t=1760591523,v1=5f2b9c…e9"
          },
          {
            "name": "X-WhaBuzz-Event-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-WhaBuzz-Event-Type",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-WhaBuzz-Delivery-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-WhaBuzz-Attempt",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "X-WhaBuzz-Received-At",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "X-WhaBuzz-Processing-Ms",
            "in": "header",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Envelope"
              },
              "examples": {
                "inbound": {
                  "$ref": "#/components/examples/EnvelopeInbound"
                },
                "status_failed": {
                  "$ref": "#/components/examples/EnvelopeStatusFailed"
                },
                "outbound": {
                  "$ref": "#/components/examples/EnvelopeOutbound"
                },
                "template_status": {
                  "$ref": "#/components/examples/EnvelopeTemplateStatus"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          }
        }
      }
    },
    "verify": {
      "post": {
        "summary": "Verify ping",
        "description": "Sent when you add an endpoint, change its URL, or press Verify. Echo the challenge.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "type": "webhook.verify",
                "challenge": "8c1f0e5b2a7d4c96b3e0f1a2d5c8e7b4",
                "endpoint_id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
                "created_at": "2026-10-16T09:20:00Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Echo the challenge as text or JSON",
            "content": {
              "application/json": {
                "example": {
                  "challenge": "8c1f0e5b2a7d4c96b3e0f1a2d5c8e7b4"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wb_live_… / wb_test_…"
      },
      "consoleSession": {
        "type": "http",
        "scheme": "bearer",
        "description": "Console session token (app.whabuzz.com). Admin routes require a platform admin."
      }
    },
    "parameters": {
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "`next_cursor` from the previous page."
      },
      "PhoneNumberId": {
        "name": "phone_number_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "1013622581841046"
      },
      "BatchId": {
        "name": "batch_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6"
      },
      "TemplateId": {
        "name": "template_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "1689556908129832"
      },
      "EndpointId": {
        "name": "endpoint_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "DeliveryId": {
        "name": "delivery_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "dlv_01JAB3Y3B6D9F2H5K8N1Q4T7W0"
      },
      "AdminTenantId": {
        "name": "tenant_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "description": "Repeat a send safely for 24 hours. Same key + same body returns the stored response; a different body returns 422."
      },
      "TenantHeader": {
        "name": "X-WhaBuzz-Tenant",
        "in": "header",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Required with an app key on tenant-scoped routes."
      }
    },
    "headers": {
      "EventId": {
        "schema": {
          "type": "string"
        },
        "description": "The `message.outbound` event recorded for this send."
      },
      "ServerTiming": {
        "schema": {
          "type": "string"
        },
        "example": "wb;dur=6, meta;dur=212"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid credentials",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "unauthorized",
                "message": "Invalid API key",
                "details": null
              },
              "request_id": "req_01JAB42C7F0H3K6N9Q2T5W8Z1C"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Not allowed for this caller",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "forbidden",
                "message": "App keys cannot call this route",
                "details": null
              },
              "request_id": "req_01JAB43D8G1J4M7P0S3V6Y9B2E"
            }
          }
        }
      },
      "TenantBlocked": {
        "description": "Tenant not approved or suspended",
        "content": {
          "application/json": {
            "examples": {
              "pending": {
                "value": {
                  "source": "whabuzz",
                  "error": {
                    "code": "tenant_not_approved",
                    "message": "Your account is under review. You will get an email when it is approved.",
                    "details": {
                      "status": "pending_approval"
                    }
                  },
                  "request_id": "req_01JAB44E9H2K5N8Q1T4W7Z0C3F"
                }
              },
              "suspended": {
                "value": {
                  "source": "whabuzz",
                  "error": {
                    "code": "tenant_suspended",
                    "message": "Account suspended: billing",
                    "details": {
                      "reason": "billing"
                    }
                  },
                  "request_id": "req_01JAB45F0J3M6P9S2V5Y8B1E4G"
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "not_found",
                "message": "Not found",
                "details": null
              },
              "request_id": "req_01JAB46G1K4N7Q0T3W6Z9C2F5H"
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "invalid_request",
                "message": "retention_days must be one of 30, 90, 180, 365",
                "details": {
                  "field": "retention_days"
                }
              },
              "request_id": "req_01JAB47H2M5P8S1V4Y7B0E3G6J"
            }
          }
        }
      },
      "NotConnected": {
        "description": "Number not connected",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "number_not_connected",
                "message": "Number 1013622581841046 is not connected: waba_not_subscribed",
                "details": {
                  "connection_detail": "waba_not_subscribed"
                }
              },
              "request_id": "req_01JAB48J3N6Q9T2W5Z8C1F4H7K"
            }
          }
        }
      },
      "MetaError": {
        "description": "Meta's error, passed through with Meta's HTTP status",
        "headers": {
          "X-WhaBuzz-Error-Source": {
            "schema": {
              "type": "string",
              "enum": [
                "meta"
              ]
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/MetaErrorBody"
            },
            "examples": {
              "not_allowed": {
                "$ref": "#/components/examples/MetaNotAllowed"
              }
            }
          }
        }
      },
      "MetaUnreachable": {
        "description": "WhaBuzz could not reach Meta. The outcome is unknown; watch for `message.status` before resending.",
        "content": {
          "application/json": {
            "example": {
              "source": "whabuzz",
              "error": {
                "code": "meta_unreachable",
                "message": "Meta did not answer within 15000 ms",
                "details": {
                  "timeout_ms": 15000
                }
              },
              "request_id": "req_01JAB49K4P7S0V3Y6B9E2G5J8M"
            }
          }
        }
      }
    },
    "examples": {
      "MetaNotAllowed": {
        "summary": "Meta 131030 passed through (HTTP 400)",
        "value": {
          "source": "meta",
          "error": {
            "message": "(#131030) Recipient phone number not in allowed list",
            "type": "OAuthException",
            "code": 131030,
            "error_data": {
              "messaging_product": "whatsapp",
              "details": "Recipient phone number not in allowed list: Add recipient phone number to recipient list and try again."
            },
            "fbtrace_id": "A1b2C3d4E5f6G7h8"
          }
        }
      },
      "MetaTemplateParams": {
        "summary": "Meta 132000 passed through (HTTP 400)",
        "value": {
          "source": "meta",
          "error": {
            "message": "(#132000) Number of parameters does not match the expected number of params",
            "type": "OAuthException",
            "code": 132000,
            "error_data": {
              "messaging_product": "whatsapp",
              "details": "body: number of localizable_params (1) does not match the expected number of params (2)"
            },
            "fbtrace_id": "B2c3D4e5F6g7H8i9"
          }
        }
      },
      "MetaInvalidToken": {
        "summary": "Meta 190 passed through (HTTP 401 from Meta becomes 401 here)",
        "value": {
          "source": "meta",
          "error": {
            "message": "Error validating access token: Session has expired.",
            "type": "OAuthException",
            "code": 190,
            "error_subcode": 463,
            "fbtrace_id": "C3d4E5f6G7h8I9j0"
          }
        }
      },
      "NumberConnected": {
        "value": {
          "phone_number_id": "1013622581841046",
          "display_phone_number": "+1 469-231-1132",
          "verified_name": "WhaBuzz Demo",
          "waba_id": "26059971920328384",
          "connection_state": "connected",
          "connection_detail": null,
          "quality_rating": "GREEN",
          "messaging_limit_tier": "TIER_250",
          "throughput_level": "STANDARD",
          "name_status": "APPROVED",
          "registered_at": "2026-10-02T06:00:00Z",
          "last_event_at": "2026-10-16T05:12:03Z"
        }
      },
      "EndpointActive": {
        "value": {
          "id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
          "url": "https://api.example.com/whatsapp/events",
          "description": "Production",
          "event_types": [
            "*"
          ],
          "status": "active",
          "verified_at": "2026-10-16T09:20:00Z",
          "secret_prefix": "whsec_Zm9v",
          "previous_secret_expires_at": null,
          "last_success_at": "2026-10-16T10:02:11Z",
          "consecutive_failures": 0
        }
      },
      "DeliveryFailed": {
        "value": {
          "id": "dlv_01JAB3Y3B6D9F2H5K8N1Q4T7W0",
          "event_id": "evt_01JAB3K9X2S8C4M7Q1V5R6T0YZ",
          "event_type": "message.inbound",
          "endpoint_id": "3c2b1a09-f8e7-4d6c-b5a4-9382716a5b4c",
          "status": "failed",
          "attempts": 3,
          "last_http_status": 503,
          "last_error": "http_5xx",
          "next_attempt_at": "2026-10-16T05:15:03Z",
          "attempt_log": [
            {
              "at": "2026-10-16T05:12:03Z",
              "http_status": null,
              "ms": 3000,
              "error": "timeout"
            },
            {
              "at": "2026-10-16T05:13:00Z",
              "http_status": 503,
              "ms": 41,
              "error": "http_5xx"
            },
            {
              "at": "2026-10-16T05:14:00Z",
              "http_status": 503,
              "ms": 38,
              "error": "http_5xx"
            }
          ],
          "is_replay": false
        }
      },
      "EnvelopeInbound": {
        "value": {
          "id": "evt_01JAB3K9X2S8C4M7Q1V5R6T0YZ",
          "type": "message.inbound",
          "api_version": "2026-10-16",
          "created_at": "2026-10-16T05:12:03.481Z",
          "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
          "waba_id": "26059971920328384",
          "phone_number_id": "1013622581841046",
          "display_phone_number": "14692311132",
          "wamid": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEAAA=",
          "wa_id": "16505551234",
          "user_id": "US.13491208655302741918",
          "dedupe_key": "msg:wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEAAA=",
          "data": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "14692311132",
              "phone_number_id": "1013622581841046"
            },
            "contacts": [
              {
                "profile": {
                  "name": "Kerry Fisher"
                },
                "wa_id": "16505551234",
                "user_id": "US.13491208655302741918"
              }
            ],
            "message": {
              "from": "16505551234",
              "from_user_id": "US.13491208655302741918",
              "id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEAAA=",
              "timestamp": "1760591523",
              "type": "text",
              "text": {
                "body": "Hi, is the 7am batch open tomorrow?"
              }
            }
          },
          "raw": {
            "object": "whatsapp_business_account",
            "entry": [
              {
                "id": "26059971920328384",
                "changes": [
                  {
                    "field": "messages",
                    "value": {
                      "messaging_product": "whatsapp",
                      "metadata": {
                        "display_phone_number": "14692311132",
                        "phone_number_id": "1013622581841046"
                      },
                      "contacts": [
                        {
                          "profile": {
                            "name": "Kerry Fisher"
                          },
                          "wa_id": "16505551234",
                          "user_id": "US.13491208655302741918"
                        }
                      ],
                      "messages": [
                        {
                          "from": "16505551234",
                          "from_user_id": "US.13491208655302741918",
                          "id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEAAA=",
                          "timestamp": "1760591523",
                          "type": "text",
                          "text": {
                            "body": "Hi, is the 7am batch open tomorrow?"
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          },
          "raw_path": "entry[0].changes[0].value.messages[0]"
        }
      },
      "EnvelopeStatusFailed": {
        "value": {
          "id": "evt_01JAB4AL5Q8T1W4Z7C0F3H6K9N",
          "type": "message.status",
          "api_version": "2026-10-16",
          "created_at": "2026-10-16T05:13:10.002Z",
          "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
          "waba_id": "26059971920328384",
          "phone_number_id": "1013622581841046",
          "display_phone_number": "14692311132",
          "wamid": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBNDMAAA=",
          "wa_id": "16505551234",
          "user_id": "US.13491208655302741918",
          "dedupe_key": "st:wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBNDMAAA=:failed:1760591523",
          "data": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "14692311132",
              "phone_number_id": "1013622581841046"
            },
            "status": {
              "id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBNDMAAA=",
              "status": "failed",
              "timestamp": "1760591523",
              "recipient_id": "16505551234",
              "recipient_user_id": "US.13491208655302741918",
              "errors": [
                {
                  "code": 131049,
                  "title": "This message was not delivered to maintain healthy ecosystem engagement.",
                  "message": "This message was not delivered to maintain healthy ecosystem engagement.",
                  "error_data": {
                    "details": "In order to maintain a healthy ecosystem engagement, the message failed to be delivered."
                  },
                  "href": "https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/"
                }
              ]
            }
          },
          "raw": {
            "object": "whatsapp_business_account",
            "entry": [
              "… full Meta body, see fixtures/meta/status_failed.json …"
            ]
          },
          "raw_path": "entry[0].changes[0].value.statuses[0]"
        }
      },
      "EnvelopeOutbound": {
        "value": {
          "id": "evt_01JAB4BM6R9V2X5A8D1G4J7M0P",
          "type": "message.outbound",
          "api_version": "2026-10-16",
          "created_at": "2026-10-16T05:12:59.120Z",
          "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
          "waba_id": "26059971920328384",
          "phone_number_id": "1013622581841046",
          "display_phone_number": "14692311132",
          "wamid": "wamid.HBgLMTY1MDU1NTEyMzQVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA",
          "wa_id": "16505551234",
          "user_id": null,
          "dedupe_key": "out:evt_01JAB4BM6R9V2X5A8D1G4J7M0P",
          "data": {
            "http_status": 200,
            "batch_id": null,
            "client_ref": null,
            "request": {
              "messaging_product": "whatsapp",
              "to": "16505551234",
              "type": "text",
              "text": {
                "body": "See you at 7."
              }
            },
            "response": {
              "messaging_product": "whatsapp",
              "contacts": [
                {
                  "input": "16505551234",
                  "wa_id": "16505551234"
                }
              ],
              "messages": [
                {
                  "id": "wamid.HBgLMTY1MDU1NTEyMzQVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA",
                  "message_status": "accepted"
                }
              ]
            }
          },
          "raw": null,
          "raw_path": null
        }
      },
      "EnvelopeTemplateStatus": {
        "value": {
          "id": "evt_01JAB4CN7S0W3Y6B9E2H5K8N1Q",
          "type": "template.status",
          "api_version": "2026-10-16",
          "created_at": "2026-10-16T06:00:00.000Z",
          "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
          "waba_id": "26059971920328384",
          "phone_number_id": null,
          "display_phone_number": null,
          "wamid": null,
          "wa_id": null,
          "user_id": null,
          "dedupe_key": "message_template_status_update:3f1c…",
          "data": {
            "field": "message_template_status_update",
            "event": "REJECTED",
            "message_template_id": 1689556908129833,
            "message_template_name": "diwali_offer",
            "message_template_language": "en",
            "reason": "INVALID_FORMAT",
            "other_info": {
              "title": "FIRST_PAUSE",
              "description": "Template body contains variables at the start or end."
            }
          },
          "raw": {
            "object": "whatsapp_business_account",
            "entry": [
              {
                "id": "26059971920328384",
                "changes": [
                  {
                    "field": "message_template_status_update",
                    "value": {
                      "event": "REJECTED",
                      "message_template_id": 1689556908129833,
                      "message_template_name": "diwali_offer",
                      "message_template_language": "en",
                      "reason": "INVALID_FORMAT",
                      "other_info": {
                        "title": "FIRST_PAUSE",
                        "description": "Template body contains variables at the start or end."
                      }
                    }
                  }
                ]
              }
            ]
          },
          "raw_path": "entry[0].changes[0].value"
        }
      }
    },
    "schemas": {
      "EventType": {
        "type": "string",
        "enum": [
          "*",
          "message.inbound",
          "message.status",
          "message.error",
          "message.echo",
          "message.outbound",
          "user.preferences",
          "batch.completed",
          "template.status",
          "template.quality",
          "template.category",
          "number.quality",
          "number.name",
          "number.connection",
          "account.update",
          "account.alerts",
          "account.capability",
          "account.security",
          "token.expiring",
          "token.invalid",
          "meta.other"
        ]
      },
      "WhaBuzzError": {
        "type": "object",
        "required": [
          "source",
          "error",
          "request_id"
        ],
        "properties": {
          "source": {
            "const": "whabuzz"
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "forbidden",
                  "tenant_not_approved",
                  "tenant_suspended",
                  "email_not_verified",
                  "not_found",
                  "number_not_connected",
                  "invalid_request",
                  "idempotency_conflict",
                  "rate_limited",
                  "webhook_verify_failed",
                  "meta_unreachable",
                  "internal_error",
                  "conflict",
                  "limit_reached",
                  "invalid_token",
                  "billing_disabled",
                  "billing_not_configured",
                  "billing_gateway_error",
                  "meta_not_configured",
                  "meta_token_invalid"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {}
            }
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "MetaErrorBody": {
        "type": "object",
        "required": [
          "source",
          "error"
        ],
        "properties": {
          "source": {
            "const": "meta"
          },
          "error": {
            "type": "object",
            "description": "Meta's `error` object, unchanged.",
            "additionalProperties": true
          }
        }
      },
      "Tenant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "active",
              "rejected",
              "suspended"
            ]
          },
          "sandbox": {
            "type": "boolean"
          },
          "retention_days": {
            "type": "integer",
            "enum": [
              30,
              90,
              180,
              365
            ]
          },
          "billing_status": {
            "type": "string",
            "enum": [
              "none",
              "trialing",
              "active",
              "past_due",
              "suspended"
            ]
          },
          "trial_ends_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "checklist": {
            "type": "object",
            "properties": {
              "number_connected": {
                "type": "boolean"
              },
              "api_key_created": {
                "type": "boolean"
              },
              "webhook_verified": {
                "type": "boolean"
              },
              "test_message_sent": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "Number": {
        "type": "object",
        "properties": {
          "phone_number_id": {
            "type": "string"
          },
          "display_phone_number": {
            "type": "string"
          },
          "verified_name": {
            "type": "string"
          },
          "waba_id": {
            "type": "string"
          },
          "connection_state": {
            "type": "string",
            "enum": [
              "pending",
              "connected",
              "disconnected"
            ]
          },
          "connection_detail": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "waba_not_subscribed",
              "not_registered",
              "no_verified_endpoint",
              "token_invalid",
              "tenant_inactive",
              null
            ]
          },
          "quality_rating": {
            "type": "string"
          },
          "messaging_limit_tier": {
            "type": "string"
          },
          "throughput_level": {
            "type": "string"
          },
          "meta_snapshot": {
            "type": "object",
            "description": "Meta's last answer for this number, verbatim."
          }
        }
      },
      "SendRequest": {
        "type": "object",
        "required": [
          "from",
          "to",
          "type"
        ],
        "description": "Meta's /messages body plus `from`. Every Meta field is accepted and forwarded unchanged.",
        "additionalProperties": true,
        "properties": {
          "from": {
            "type": "string",
            "description": "phone_number_id or E.164 of one of your numbers"
          },
          "messaging_product": {
            "type": "string",
            "default": "whatsapp"
          },
          "to": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "event_types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventType"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_verification",
              "active",
              "disabled"
            ]
          },
          "verified_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "secret_prefix": {
            "type": "string"
          },
          "previous_secret_expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "consecutive_failures": {
            "type": "integer"
          }
        }
      },
      "Envelope": {
        "type": "object",
        "required": [
          "id",
          "type",
          "api_version",
          "created_at",
          "tenant_id",
          "dedupe_key",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "evt_ + ULID"
          },
          "type": {
            "$ref": "#/components/schemas/EventType"
          },
          "api_version": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "tenant_id": {
            "type": "string",
            "format": "uuid"
          },
          "waba_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone_number_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_phone_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "wamid": {
            "type": [
              "string",
              "null"
            ]
          },
          "wa_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "user_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Customer business-scoped user id when Meta sends one."
          },
          "dedupe_key": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "description": "Meta objects verbatim."
          },
          "raw": {
            "type": [
              "object",
              "null"
            ],
            "description": "The complete POST body Meta sent."
          },
          "raw_path": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    }
  }
}
