openapi: 3.0.3
info:
  title: Abacato Public API
  description: >
    Public REST API for the Abacato WhatsApp platform. Lets a customer's own
    systems send WhatsApp messages, list imported contacts, and check the
    WhatsApp connection status. Authenticated with an API key created in the
    Abacato dashboard.
  version: "1.0.0"
  contact:
    name: Abacato
    url: https://api.abacato.vps.aprendendoai.com

servers:
  - url: https://api.abacato.vps.aprendendoai.com
    description: Production

security:
  - ApiKeyAuth: []

paths:
  /api/v1/public/messages/text:
    post:
      summary: Send a text message
      operationId: sendText
      tags: [Messages]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [to, text]
              properties:
                to:
                  type: string
                  description: Recipient phone number, digits only.
                  example: "5511888888888"
                text:
                  type: string
                  maxLength: 4096
                  description: Message body.
                  example: "Olá! Essa é uma mensagem de teste."
      responses:
        "201":
          description: Message sent and persisted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    $ref: "#/components/schemas/Message"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

  /api/v1/public/messages/template:
    post:
      summary: Send a template message
      description: >
        Only available for accounts connected via the official Meta Cloud API
        (not Evolution/QR Code). The template must already be approved on the
        account's WhatsApp Business Account.
      operationId: sendTemplate
      tags: [Messages]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [to, templateName]
              properties:
                to:
                  type: string
                  description: Recipient phone number, digits only.
                  example: "5511888888888"
                templateName:
                  type: string
                  example: "pedido_atualizado"
                language:
                  type: string
                  default: pt_BR
                  example: "pt_BR"
                components:
                  type: array
                  items: {}
                  description: Meta template components used to fill variables.
      responses:
        "201":
          description: Template message sent and persisted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    $ref: "#/components/schemas/Message"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

  /api/v1/public/contacts:
    get:
      summary: List imported contacts
      operationId: listContacts
      tags: [Contacts]
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 1 }
        - name: limit
          in: query
          schema: { type: integer, default: 50, maximum: 100 }
        - name: search
          in: query
          schema: { type: string }
          description: Filters by contact name or phone number.
      responses:
        "200":
          description: Paginated list of contacts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  contacts:
                    type: array
                    items:
                      $ref: "#/components/schemas/Contact"
                  total:
                    type: integer
                  page:
                    type: integer
                  limit:
                    type: integer
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

  /api/v1/public/whatsapp/status:
    get:
      summary: Get the connected WhatsApp account status
      operationId: getWhatsAppStatus
      tags: [WhatsApp]
      responses:
        "200":
          description: The active WhatsApp account, or null if none is connected.
          content:
            application/json:
              schema:
                type: object
                properties:
                  account:
                    oneOf:
                      - $ref: "#/components/schemas/WhatsAppAccount"
                      - type: "null"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

  schemas:
    Message:
      type: object
      properties:
        id: { type: string, format: uuid }
        direction: { type: string, enum: [outbound, inbound] }
        recipientNumber: { type: string }
        messageType: { type: string, enum: [text, template] }
        templateName: { type: string, nullable: true }
        content: { type: string, nullable: true }
        wamid: { type: string, nullable: true }
        status: { type: string, enum: [sent, delivered, read, failed] }
        errorMessage: { type: string, nullable: true }
        sentAt: { type: string, format: date-time }
        statusUpdatedAt: { type: string, format: date-time, nullable: true }
        createdAt: { type: string, format: date-time }

    Contact:
      type: object
      properties:
        id: { type: string, format: uuid }
        phoneNumber: { type: string }
        name: { type: string, nullable: true }
        createdAt: { type: string, format: date-time }
        updatedAt: { type: string, format: date-time }

    WhatsAppAccount:
      type: object
      properties:
        id: { type: string, format: uuid }
        provider: { type: string, enum: [meta_cloud, evolution] }
        wabaId: { type: string, nullable: true }
        phoneNumberId: { type: string, nullable: true }
        evolutionInstanceName: { type: string, nullable: true }
        displayName: { type: string, nullable: true }
        displayPhoneNumber: { type: string, nullable: true }
        qualityRating: { type: string, nullable: true }
        isCoex: { type: boolean }
        status: { type: string, enum: [active, disconnected] }
        connectedAt: { type: string, format: date-time }

    Error:
      type: object
      properties:
        error:
          type: string

  responses:
    BadRequest:
      description: Invalid request body.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    Unauthorized:
      description: Missing, invalid, or revoked API key.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    RateLimited:
      description: Rate limit exceeded (1000 requests / 15 min per API key).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }

tags:
  - name: Messages
  - name: Contacts
  - name: WhatsApp
