{
  "openapi": "3.1.0",
  "info": {
    "title": "NexxiSend — Universal Messaging API",
    "version": "1.0.0",
    "description": "Uma única API para SMS, WhatsApp e E-mail, com roteamento NexxiRoute, consentimento, supressão e idempotência obrigatória."
  },
  "servers": [
    {
      "url": "/",
      "description": "Mesma origem da aplicação"
    }
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Messages",
      "description": "Envio unificado de mensagens"
    }
  ],
  "paths": {
    "/api/public/v1/messages": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "sendMessage",
        "summary": "Envia uma mensagem em qualquer canal suportado",
        "description": "Requer uma API key do console com escopo messages:send. Use dry_run para validar consentimento, supressão e rota sem enviar nada.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 6,
              "maxLength": 120
            },
            "description": "Chave de idempotência. A mesma chave nunca gera um segundo envio; também pode ir no corpo como idempotency_key."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendMessageRequest"
              },
              "examples": {
                "sms": {
                  "summary": "SMS simples",
                  "value": {
                    "channel": "sms",
                    "to": "+5511999999999",
                    "sms": {
                      "body": "Seu código é 123456"
                    },
                    "idempotency_key": "otp-2026-02-01-abc123"
                  }
                },
                "whatsappTemplate": {
                  "summary": "WhatsApp com template aprovado",
                  "value": {
                    "channel": "whatsapp",
                    "to": "+5511999999999",
                    "whatsapp": {
                      "template": {
                        "name": "pedido_enviado",
                        "language": "pt_BR",
                        "variables": [
                          "1234"
                        ]
                      }
                    }
                  }
                },
                "email": {
                  "summary": "E-mail transacional",
                  "value": {
                    "channel": "email",
                    "to": "cliente@exemplo.com",
                    "email": {
                      "subject": "Pedido confirmado",
                      "html": "<p>Obrigado!</p>"
                    }
                  }
                },
                "dryRun": {
                  "summary": "Validação sem envio",
                  "value": {
                    "channel": "sms",
                    "to": "+5511999999999",
                    "sms": {
                      "body": "teste"
                    },
                    "dry_run": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem aceita, reaproveitada por idempotência ou validada em dry_run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendMessageResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key criada no console (prefixo nxs_live_). Nunca use no navegador."
      }
    },
    "responses": {
      "Error": {
        "description": "Erro padronizado",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "SendMessageRequest": {
        "type": "object",
        "required": [
          "channel",
          "to"
        ],
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "sms",
              "whatsapp",
              "email"
            ]
          },
          "to": {
            "type": "string",
            "minLength": 5,
            "maxLength": 200
          },
          "client_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "country": {
            "type": "string",
            "maxLength": 4,
            "nullable": true
          },
          "require_consent": {
            "type": "boolean"
          },
          "dry_run": {
            "type": "boolean"
          },
          "idempotency_key": {
            "type": "string",
            "minLength": 6,
            "maxLength": 120
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "sms": {
            "type": "object",
            "required": [
              "body"
            ],
            "properties": {
              "body": {
                "type": "string",
                "minLength": 1,
                "maxLength": 1600
              },
              "sender_id": {
                "type": "string",
                "maxLength": 24,
                "nullable": true
              }
            }
          },
          "whatsapp": {
            "type": "object",
            "properties": {
              "text": {
                "type": "string",
                "maxLength": 4096,
                "nullable": true
              },
              "template": {
                "type": "object",
                "required": [
                  "name",
                  "language"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "language": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 10
                  },
                  "variables": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 500
                    }
                  }
                }
              }
            }
          },
          "email": {
            "type": "object",
            "required": [
              "subject"
            ],
            "properties": {
              "subject": {
                "type": "string",
                "minLength": 1,
                "maxLength": 300
              },
              "html": {
                "type": "string",
                "nullable": true
              },
              "text": {
                "type": "string",
                "nullable": true
              },
              "from": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 120,
                    "nullable": true
                  }
                }
              },
              "reply_to": {
                "type": "string",
                "format": "email",
                "nullable": true
              }
            }
          }
        }
      },
      "SendMessageResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "message_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "status": {
                "type": "string"
              },
              "channel": {
                "type": "string"
              },
              "provider_code": {
                "type": "string",
                "nullable": true
              },
              "destination_masked": {
                "type": "string"
              },
              "dry_run": {
                "type": "boolean"
              },
              "reused": {
                "type": "boolean",
                "description": "true quando a idempotência reaproveitou um envio"
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {}
            }
          }
        }
      }
    }
  }
}