> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bevits.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a WhatsApp Official campaign as a draft

> Creates a WhatsApp Official campaign as a draft with a new template and submits the template to Meta for review. No message is sent: after approval, a person picks the audience and sends the campaign in Bevits. With validate_only, it only validates the campaign, saving nothing and without contacting Meta. Each saved call submits one template to Meta; do not repeat a call that succeeded. Requires an API key with the write scope.



## OpenAPI

````yaml /openapi.en.json post /v1/whatsapp-campaigns
openapi: 3.1.0
info:
  title: Bevits API
  version: 1.0.0
  description: >-
    Public API for querying CRM, purchase, and automation data from a Bevits
    organization, creating automations as drafts for review and activation, and
    creating WhatsApp Official campaigns as drafts.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.bevits.com
    description: Production
security:
  - bearerAuth: []
tags:
  - name: System
    description: API availability.
  - name: Identity
    description: Organization and API key identity.
  - name: Customers
    description: Customers and their relationships.
  - name: Segments
    description: Customer segments.
  - name: Purchases
    description: Purchases imported from integrations.
  - name: CRM data
    description: Tags and attribute definitions.
  - name: Automations
    description: Automation flows.
  - name: Campaigns
    description: Email campaigns.
paths:
  /v1/whatsapp-campaigns:
    post:
      tags:
        - Campaigns
      summary: Create a WhatsApp Official campaign as a draft
      description: >-
        Creates a WhatsApp Official campaign as a draft with a new template and
        submits the template to Meta for review. No message is sent: after
        approval, a person picks the audience and sends the campaign in Bevits.
        With validate_only, it only validates the campaign, saving nothing and
        without contacting Meta. Each saved call submits one template to Meta;
        do not repeat a call that succeeded. Requires an API key with the write
        scope.
      operationId: createWhatsAppCampaign
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WhatsAppCampaignSpec'
            example:
              name: Black Friday VIP
              template:
                category: marketing
                header:
                  type: image
                  url: https://cdn.loja.com/bf.png
                body: >-
                  Oi {{1}}! A Black Friday começou: {{2}} em toda a loja.
                  Aproveite 👇
                variables:
                  - example: Maria
                    fill:
                      type: first_name
                      fallback: cliente
                  - example: 30% off
                    fill:
                      type: fixed_text
                      text: 30% off
                footer: Responda SAIR para não receber
                buttons:
                  - type: url
                    text: Ver ofertas
                    url: https://loja.com/black-friday
      responses:
        '200':
          $ref: '#/components/responses/WhatsAppCampaignDraft'
        '400':
          $ref: '#/components/responses/InvalidBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/WriteScopeRequired'
        '409':
          $ref: '#/components/responses/IdempotencyConflict'
        '422':
          $ref: '#/components/responses/WhatsAppCampaignValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      description: >-
        Unique key for the operation. Repeating the same key with the same body
        returns the original response instead of running it again.
      schema:
        type: string
  schemas:
    WhatsAppCampaignSpec:
      type: object
      required:
        - name
        - template
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 120
          description: Campaign name shown in Bevits; it also names the template.
        official_account_id:
          type: string
          pattern: ^waa_[A-Za-z0-9_-]+$
          description: >-
            WhatsApp number that sends the campaign. Needed only when the store
            has several numbers and none is the default; in that case, the error
            lists the options.
        template:
          $ref: '#/components/schemas/WhatsAppCampaignTemplateSpec'
        validate_only:
          type: boolean
          default: false
          description: >-
            When true, only validates the campaign and its template, saving
            nothing and without contacting Meta.
    WhatsAppCampaignTemplateSpec:
      type: object
      required:
        - body
      properties:
        category:
          type: string
          enum:
            - marketing
            - utility
          default: marketing
          description: >-
            Promotions are marketing; Meta re-categorizes or rejects utility
            templates with promotional content.
        language:
          type: string
          enum:
            - pt_BR
            - en_US
          default: pt_BR
        header:
          description: 'Optional header: text or media.'
          oneOf:
            - $ref: '#/components/schemas/WhatsAppTemplateTextHeader'
            - $ref: '#/components/schemas/WhatsAppTemplateMediaHeader'
        body:
          type: string
          minLength: 1
          maxLength: 1024
          description: >-
            Message text. WhatsApp formatting (*bold*, _italic_) and emoji are
            allowed. Variables are {{1}}, {{2}}… in order, never at the very
            start or end of the text.
        variables:
          type: array
          maxItems: 20
          default: []
          description: One entry per {{n}} in the text, in the same order.
          items:
            $ref: '#/components/schemas/WhatsAppCampaignVariable'
        footer:
          type: string
          minLength: 1
          maxLength: 60
          description: Plain-text footer, without emoji, formatting, or variables.
        buttons:
          type: array
          maxItems: 10
          default: []
          description: >-
            Up to 10 buttons, with at most 2 link buttons, 1 phone button, and 1
            copy-code button.
          items:
            oneOf:
              - $ref: '#/components/schemas/WhatsAppTemplateUrlButton'
              - $ref: '#/components/schemas/WhatsAppTemplateQuickReplyButton'
              - $ref: '#/components/schemas/WhatsAppTemplatePhoneButton'
              - $ref: '#/components/schemas/WhatsAppTemplateCopyCodeButton'
    WhatsAppCampaignDraft:
      type: object
      required:
        - object
        - validate_only
        - name
        - status
        - template
        - pending
        - next_step
      properties:
        object:
          type: string
          const: whatsapp_campaign_draft
        validate_only:
          type: boolean
          description: >-
            true when the campaign was only validated; nothing was saved or sent
            to Meta.
        id:
          type: string
          pattern: ^tcp_[A-Za-z0-9_-]+$
        name:
          type: string
        status:
          type: string
          const: draft
        html_url:
          type: string
          format: uri
          description: >-
            Link to the campaign in Bevits, where a person picks the audience
            and sends it.
        template:
          type: object
          required:
            - category
            - language
            - preview
          properties:
            id:
              type: string
              pattern: ^wtp_[A-Za-z0-9_-]+$
            category:
              type: string
              enum:
                - marketing
                - utility
            language:
              type: string
            status:
              type: string
              description: >-
                Meta review status: pending, approved, or rejected. Absent when
                the campaign was only validated.
            preview:
              type: string
              description: >-
                Text with the examples in place of each {{n}}, as Meta reviewers
                see it.
        pending:
          type: array
          description: >-
            What is still missing before sending, such as Meta's approval and
            choosing the audience.
          items:
            type: string
        next_step:
          type: string
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    RateLimitErrorResponse:
      allOf:
        - $ref: '#/components/schemas/ErrorResponse'
        - type: object
          required:
            - retry_after
          properties:
            retry_after:
              type: integer
              minimum: 1
              description: Seconds before retrying.
    WhatsAppTemplateTextHeader:
      type: object
      required:
        - type
        - text
      properties:
        type:
          type: string
          const: text
        text:
          type: string
          minLength: 1
          maxLength: 60
          description: 'Plain text: no emoji, *formatting*, line breaks, or variables.'
    WhatsAppTemplateMediaHeader:
      type: object
      required:
        - type
        - url
      properties:
        type:
          type: string
          enum:
            - image
            - video
            - document
        url:
          type: string
          format: uri
          maxLength: 512
          description: >-
            Public HTTPS URL of the file (image: JPEG or PNG up to 5 MB; video:
            MP4 up to 16 MB; document: PDF up to 100 MB). It is sent to Meta as
            the review sample and used as the campaign media.
        filename:
          type: string
          minLength: 1
          maxLength: 255
          description: Document name customers see.
    WhatsAppCampaignVariable:
      type: object
      required:
        - example
      properties:
        example:
          type: string
          minLength: 1
          maxLength: 200
          description: Sample value Meta shows to its reviewers. Required for every {{n}}.
        fill:
          description: >-
            What each customer receives: their first name, or the same text for
            everyone. Omit it to choose later in the campaign editor.
          oneOf:
            - type: object
              required:
                - type
              properties:
                type:
                  type: string
                  const: first_name
                fallback:
                  type: string
                  minLength: 1
                  maxLength: 60
                  description: Sent when the customer has no name, such as "cliente".
            - type: object
              required:
                - type
                - text
              properties:
                type:
                  type: string
                  const: fixed_text
                text:
                  type: string
                  minLength: 1
                  maxLength: 200
    WhatsAppTemplateUrlButton:
      type: object
      required:
        - type
        - text
        - url
      properties:
        type:
          type: string
          const: url
        text:
          type: string
          minLength: 1
          maxLength: 25
        url:
          type: string
          format: uri
          maxLength: 2000
          description: >-
            The button's real destination. Bevits sends Meta its click-tracking
            short link instead.
    WhatsAppTemplateQuickReplyButton:
      type: object
      required:
        - type
        - text
      properties:
        type:
          type: string
          const: quick_reply
        text:
          type: string
          minLength: 1
          maxLength: 25
    WhatsAppTemplatePhoneButton:
      type: object
      required:
        - type
        - text
        - phone_number
      properties:
        type:
          type: string
          const: phone_number
        text:
          type: string
          minLength: 1
          maxLength: 25
        phone_number:
          type: string
          pattern: ^\+\d{8,15}$
          description: Phone number in international format, such as +5511999999999.
    WhatsAppTemplateCopyCodeButton:
      type: object
      required:
        - type
        - code
      properties:
        type:
          type: string
          const: copy_code
        code:
          type: string
          minLength: 1
          maxLength: 15
          description: Coupon code the customer copies.
    Error:
      type: object
      required:
        - type
        - message
        - request_id
      properties:
        type:
          type: string
          enum:
            - authentication_error
            - conflict
            - internal_error
            - invalid_request
            - not_found
            - permission_denied
            - rate_limited
            - validation_error
        message:
          type: string
        param:
          type: string
        request_id:
          type: string
          pattern: ^req_[a-f0-9]{24}$
  responses:
    WhatsAppCampaignDraft:
      description: >-
        Campaign validated or saved as a draft, with its template submitted to
        Meta for review.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WhatsAppCampaignDraft'
    InvalidBody:
      description: >-
        Missing request body, a body that is not a JSON object, or an invalid
        route parameter.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing, invalid, expired, or revoked API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: authentication_error
              message: Invalid API key.
              request_id: req_07f6cdc3c20249d6afcd90b4
    WriteScopeRequired:
      description: The API key does not have the write scope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: permission_denied
              message: This API key does not have the required "write" scope.
              param: scope
              request_id: req_07f6cdc3c20249d6afcd90b4
    IdempotencyConflict:
      description: The Idempotency-Key was already used with a different request body.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    WhatsAppCampaignValidationError:
      description: >-
        The campaign can't be created. The message lists every problem, each
        with the field path, or gives Meta's rejection reason. When the store
        has several WhatsApp numbers and none is the default, the message lists
        the official_account_id options.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: validation_error
              message: >-
                The campaign has 1 problem; fix all of them and retry:

                - template.variables: The body has 2 variables but
                template.variables has 1 entry. Give exactly one per {{n}}, in
                order.
              param: template.variables
              request_id: req_07f6cdc3c20249d6afcd90b4
    RateLimited:
      description: Request limit exceeded.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitErrorResponse'
    InternalError:
      description: Unexpected server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  headers:
    RetryAfter:
      description: Seconds before retrying.
      schema:
        type: integer
        minimum: 1
    RateLimitLimit:
      description: Total limit for the current window.
      schema:
        type: integer
        example: 600
    RateLimitRemaining:
      description: Requests remaining in the current window.
      schema:
        type: integer
        example: 599
    RateLimitReset:
      description: UTC instant when the current window ends.
      schema:
        type: string
        format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: bvt_live_...
      description: API key created in the organization settings.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.