{
  "openapi": "3.1.0",
  "info": {
    "title": "API de Notificações SMS",
    "version": "0.1.0",
    "description": "Envie notificações SMS, gira templates, contactos, listas, saldo e histórico de envios para contas de comerciante IZI Pay."
  },
  "servers": [
    {
      "url": "https://sms.izipay.ao",
      "description": "Production"
    },
    {
      "url": "https://sms-sandbox.izipay.ao",
      "description": "Sandbox"
    }
  ],
  "tags": [
    {
      "name": "Autenticação",
      "description": "Registar utilizadores, verificar emails, emitir tokens, recuperar acesso e consultar o perfil do utilizador autenticado."
    },
    {
      "name": "MFA",
      "description": "Ativar ou remover autenticação multifator para um utilizador autenticado."
    },
    {
      "name": "Acesso de Comerciante",
      "description": "Gerir quais utilizadores podem aceder a uma conta de comerciante."
    },
    {
      "name": "Faturação",
      "description": "Consultar subscrição, faturas e utilização do comerciante."
    },
    {
      "name": "Pagamentos",
      "description": "Criar, listar, sincronizar e cancelar operações de pagamento."
    },
    {
      "name": "Referências PPR",
      "description": "Criar e gerir referências de pagamento PPR."
    },
    {
      "name": "Operações de Terminal",
      "description": "Abrir, fechar e consultar o estado de terminais GPO."
    },
    {
      "name": "Conta SMS",
      "description": "Consultar o utilizador autenticado e a configuração de remetente SMS do comerciante."
    },
    {
      "name": "Saldo SMS",
      "description": "Consultar o saldo SMS e o histórico de movimentos da conta de comerciante."
    },
    {
      "name": "Templates SMS",
      "description": "Criar e gerir templates reutilizáveis de mensagens SMS."
    },
    {
      "name": "Contactos SMS",
      "description": "Gerir contactos SMS e listas de contactos para envios em massa."
    },
    {
      "name": "Envio SMS",
      "description": "Enviar mensagens SMS e consultar o histórico de mensagens enviadas."
    },
    {
      "name": "SMS Agendado",
      "description": "Agendar mensagens SMS e listar envios agendados."
    }
  ],
  "paths": {
    "/api/Empresa/ObterUtilizadorLogado": {
      "get": {
        "tags": [
          "Conta SMS"
        ],
        "summary": "Obter utilizador SMS autenticado",
        "description": "Método e rota: `GET /api/Empresa/ObterUtilizadorLogado`. Retorna o utilizador Identity associado ao contexto SMS do comerciante atual. Use para confirmar qual comerciante e utilizador estão representados pelo token bearer.",
        "operationId": "getSmsLoggedUser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dados do utilizador autenticado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsLoggedUser"
                },
                "example": {
                  "userId": "11111111-1111-1111-1111-111111111111",
                  "merchantId": "BB1376D9-03D3-45C6-82FA-61F4270D27B6",
                  "email": "merchant@example.com",
                  "name": "Jane Merchant"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Empresa/ObterDadosDaEmpresa": {
      "get": {
        "tags": [
          "Conta SMS"
        ],
        "summary": "Obter remetente SMS do comerciante",
        "description": "Método e rota: `GET /api/Empresa/ObterDadosDaEmpresa`. Retorna os dados do comerciante e o remetente configurado para envios SMS. Use antes de enviar mensagens quando a aplicação precisa apresentar ou validar o remetente visível para os destinatários.",
        "operationId": "getSmsMerchantData",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dados do comerciante e remetente SMS.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsMerchant"
                },
                "example": {
                  "merchantId": "BB1376D9-03D3-45C6-82FA-61F4270D27B6",
                  "nome": "Comerciante IZI",
                  "remetenteSms": "IZIPAY"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Saldo/ObterSaldo": {
      "get": {
        "tags": [
          "Saldo SMS"
        ],
        "summary": "Obter saldo SMS",
        "description": "Método e rota: `GET /api/Saldo/ObterSaldo`. Retorna o saldo SMS atual do comerciante autenticado. Este endpoint é apenas de consulta e não adiciona nem ajusta saldo.",
        "operationId": "getSmsBalance",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Saldo SMS atual.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsBalance"
                },
                "example": {
                  "merchantId": "BB1376D9-03D3-45C6-82FA-61F4270D27B6",
                  "saldoAtual": 250,
                  "unidade": "sms",
                  "atualizadoEm": "2026-06-14T10:30:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/HistoricoSaldo/ObterHistoricoSaldo": {
      "get": {
        "tags": [
          "Saldo SMS"
        ],
        "summary": "Obter histórico de saldo SMS",
        "description": "Método e rota: `GET /api/HistoricoSaldo/ObterHistoricoSaldo`. Retorna movimentos que alteraram ou consumiram o saldo SMS do comerciante. Use para reconciliação e ecrãs de atividade da conta.",
        "operationId": "getSmsBalanceHistory",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Movimentos do saldo SMS.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SmsBalanceLedgerEntry"
                  }
                },
                "example": [
                  {
                    "id": 1001,
                    "tipo": "Debito",
                    "quantidade": 1,
                    "saldoDepois": 249,
                    "descricao": "SMS enviado",
                    "criadoEm": "2026-06-14T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/TemplatesSMS/CriarTemplate": {
      "post": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Criar template SMS",
        "description": "Método e rota: `POST /api/TemplatesSMS/CriarTemplate`. Cria um template SMS reutilizável para o comerciante autenticado. Use templates para mensagens enviadas repetidamente com o mesmo texto.",
        "operationId": "createSmsTemplate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsTemplateRequest"
              },
              "example": {
                "nome": "Codigo de verificacao",
                "conteudo": "Ola {{customerName}}, o seu codigo e 1234."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template criado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsTemplate"
                },
                "example": {
                  "id": 42,
                  "nome": "Codigo de verificacao",
                  "conteudo": "Ola {{customerName}}, o seu codigo e 1234.",
                  "criadoEm": "2026-06-14T10:30:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/TemplatesSMS/ListarTemplatesSms": {
      "get": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Listar templates SMS",
        "description": "Método e rota: `GET /api/TemplatesSMS/ListarTemplatesSms`. Retorna os templates SMS criados pelo comerciante autenticado.",
        "operationId": "listSmsTemplates",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Templates SMS.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SmsTemplate"
                  }
                },
                "example": [
                  {
                    "id": 42,
                    "nome": "Codigo de verificacao",
                    "conteudo": "Ola {{customerName}}, o seu codigo e 1234.",
                    "criadoEm": "2026-06-14T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/TemplatesSMS/ObterTemplatesSmsPorId/{templateId}": {
      "get": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Obter template SMS por ID",
        "description": "Método e rota: `GET /api/TemplatesSMS/ObterTemplatesSmsPorId/{templateId}`. Consulta um template SMS pelo seu identificador.",
        "operationId": "getSmsTemplateById",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsTemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Detalhes do template SMS.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsTemplate"
                },
                "example": {
                  "id": 42,
                  "nome": "Codigo de verificacao",
                  "conteudo": "Ola {{customerName}}, o seu codigo e 1234."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/TemplatesSMS/pesquisarTemplateSMSporData": {
      "get": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Pesquisar templates SMS por data",
        "description": "Método e rota: `GET /api/TemplatesSMS/pesquisarTemplateSMSporData`. Pesquisa templates SMS criados num dia, mês e ano específicos.",
        "operationId": "searchSmsTemplatesByDate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Day"
          },
          {
            "$ref": "#/components/parameters/Month"
          },
          {
            "$ref": "#/components/parameters/Year"
          }
        ],
        "responses": {
          "200": {
            "description": "Templates SMS encontrados.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SmsTemplate"
                  }
                },
                "example": [
                  {
                    "id": 42,
                    "nome": "Codigo de verificacao",
                    "conteudo": "Ola {{customerName}}, o seu codigo e 1234."
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/TemplatesSMS/AtualizarTemplate/{templateId}": {
      "put": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Atualizar template SMS",
        "description": "Método e rota: `PUT /api/TemplatesSMS/AtualizarTemplate/{templateId}`. Atualiza o nome e o conteúdo de um template SMS existente.",
        "operationId": "updateSmsTemplate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsTemplateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsTemplateRequest"
              },
              "example": {
                "nome": "Codigo de verificacao atualizado",
                "conteudo": "Mensagem de teste atualizada."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template atualizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsTemplate"
                },
                "example": {
                  "id": 42,
                  "nome": "Codigo de verificacao atualizado",
                  "conteudo": "Mensagem de teste atualizada."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/TemplatesSMS/DeletarTemplate/{templateId}": {
      "delete": {
        "tags": [
          "Templates SMS"
        ],
        "summary": "Eliminar template SMS",
        "description": "Método e rota: `DELETE /api/TemplatesSMS/DeletarTemplate/{templateId}`. Elimina um template SMS que já não é necessário.",
        "operationId": "deleteSmsTemplate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsTemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template eliminado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsActionResult"
                },
                "example": {
                  "success": true,
                  "message": "Template eliminado."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Contactos/CadastrarContacto": {
      "post": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Criar contacto SMS",
        "description": "Método e rota: `POST /api/Contactos/CadastrarContacto`. Cria um contacto SMS para o comerciante autenticado.",
        "operationId": "createSmsContact",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsContactRequest"
              },
              "example": {
                "nome": "Jane Customer",
                "telefone": "923000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contacto criado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContact"
                },
                "example": {
                  "contactoId": 120,
                  "nome": "Jane Customer",
                  "telefone": "923000000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Contactos/ListarContactos": {
      "get": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Listar contactos SMS",
        "description": "Método e rota: `GET /api/Contactos/ListarContactos`. Retorna uma lista paginada de contactos do comerciante autenticado.",
        "operationId": "listSmsContacts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PageNumber"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "Contactos paginados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContactPage"
                },
                "example": {
                  "items": [
                    {
                      "contactoId": 120,
                      "nome": "Jane Customer",
                      "telefone": "923000000"
                    }
                  ],
                  "pageNumber": 1,
                  "pageSize": 20,
                  "totalCount": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Contactos/ObterContacto/{contactoId}": {
      "get": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Obter contacto SMS por ID",
        "description": "Método e rota: `GET /api/Contactos/ObterContacto/{contactoId}`. Consulta um contacto SMS pelo seu identificador.",
        "operationId": "getSmsContactById",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "Detalhes do contacto.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContact"
                },
                "example": {
                  "contactoId": 120,
                  "nome": "Jane Customer",
                  "telefone": "923000000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Contactos/AtualizarContacto/{contactoId}": {
      "put": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Atualizar contacto SMS",
        "description": "Método e rota: `PUT /api/Contactos/AtualizarContacto/{contactoId}`. Atualiza o nome e o telefone de um contacto.",
        "operationId": "updateSmsContact",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsContactId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsContactRequest"
              },
              "example": {
                "nome": "Jane Customer Updated",
                "telefone": "923000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contacto atualizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContact"
                },
                "example": {
                  "contactoId": 120,
                  "nome": "Jane Customer Updated",
                  "telefone": "923000000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Contactos/DeletarContacto/{contactoId}": {
      "delete": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Eliminar contacto SMS",
        "description": "Método e rota: `DELETE /api/Contactos/DeletarContacto/{contactoId}`. Elimina um contacto da conta do comerciante autenticado.",
        "operationId": "deleteSmsContact",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "Contacto eliminado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsActionResult"
                },
                "example": {
                  "success": true,
                  "message": "Contacto eliminado."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Contactos/criar-lista-com-contactos": {
      "post": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Criar lista de contactos",
        "description": "Método e rota: `POST /api/Contactos/criar-lista-com-contactos`. Cria uma lista de contactos e associa contactos existentes através dos seus IDs.",
        "operationId": "createSmsContactList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsContactListRequest"
              },
              "example": {
                "nome": "Alertas de pagamento",
                "contactoIds": [
                  120
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lista de contactos criada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContactList"
                },
                "example": {
                  "listaDeContactoId": 30,
                  "nome": "Alertas de pagamento",
                  "contactoIds": [
                    120
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Contactos/ListarListasDeContactos": {
      "get": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Listar listas de contactos",
        "description": "Método e rota: `GET /api/Contactos/ListarListasDeContactos`. Retorna uma lista paginada de listas de contactos SMS do comerciante autenticado.",
        "operationId": "listSmsContactLists",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PageNumber"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "Listas de contactos paginadas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContactListPage"
                },
                "example": {
                  "items": [
                    {
                      "listaDeContactoId": 30,
                      "nome": "Alertas de pagamento",
                      "totalContactos": 1
                    }
                  ],
                  "pageNumber": 1,
                  "pageSize": 20,
                  "totalCount": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Contactos/ObterListaDeContactos/{listaId}": {
      "get": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Obter lista de contactos por ID",
        "description": "Método e rota: `GET /api/Contactos/ObterListaDeContactos/{listaId}`. Consulta uma lista de contactos e os contactos associados.",
        "operationId": "getSmsContactListById",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsContactListId"
          }
        ],
        "responses": {
          "200": {
            "description": "Detalhes da lista de contactos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsContactList"
                },
                "example": {
                  "listaDeContactoId": 30,
                  "nome": "Alertas de pagamento",
                  "contactos": [
                    {
                      "contactoId": 120,
                      "nome": "Jane Customer",
                      "telefone": "923000000"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Contactos/AdicionarContactoALista": {
      "post": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Adicionar contacto a lista",
        "description": "Método e rota: `POST /api/Contactos/AdicionarContactoALista`. Adiciona um contacto existente a uma lista de contactos SMS existente.",
        "operationId": "addSmsContactToList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddSmsContactToListRequest"
              },
              "example": {
                "contactoId": 120,
                "listaId": 30
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contacto adicionado a lista.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsActionResult"
                },
                "example": {
                  "success": true,
                  "message": "Contacto adicionado a lista."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Contactos/DeletarListaDeContactos/{listaId}": {
      "delete": {
        "tags": [
          "Contactos SMS"
        ],
        "summary": "Eliminar lista de contactos",
        "description": "Método e rota: `DELETE /api/Contactos/DeletarListaDeContactos/{listaId}`. Elimina uma lista de contactos. Os contactos podem continuar disponíveis fora da lista eliminada.",
        "operationId": "deleteSmsContactList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SmsContactListId"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de contactos eliminada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsActionResult"
                },
                "example": {
                  "success": true,
                  "message": "Lista de contactos eliminada."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/Envio/enviarSms": {
      "post": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Enviar SMS de texto",
        "description": "Método e rota: `POST /api/Envio/enviarSms`. Envia uma mensagem SMS de texto para um ou mais números de destino usando a conta SMS do comerciante autenticado.",
        "operationId": "sendSmsText",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendSmsTextRequest"
              },
              "example": {
                "numerosDestino": [
                  "923000000"
                ],
                "conteudo": "O seu pagamento IZI Pay foi recebido."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Envio SMS aceite.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsSendResult"
                },
                "example": {
                  "batchId": "sms-batch-123",
                  "totalDestinatarios": 1,
                  "estado": "Accepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/enviarSmsTemplate": {
      "post": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Enviar SMS com template",
        "description": "Método e rota: `POST /api/Envio/enviarSmsTemplate`. Envia uma mensagem SMS usando um ID de template existente.",
        "operationId": "sendSmsTemplate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendSmsTemplateRequest"
              },
              "example": {
                "smsId": 42,
                "numerosDestino": [
                  "923000000"
                ],
                "remetente": "IZIPAY"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Envio SMS com template aceite.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsSendResult"
                },
                "example": {
                  "batchId": "sms-batch-124",
                  "totalDestinatarios": 1,
                  "estado": "Accepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/enviar-para-lista": {
      "post": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Enviar SMS para lista de contactos",
        "description": "Método e rota: `POST /api/Envio/enviar-para-lista`. Envia um SMS de texto para todos os contactos de uma lista existente.",
        "operationId": "sendSmsToContactList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendSmsListRequest"
              },
              "example": {
                "listaId": 30,
                "remetente": "IZIPAY",
                "conteudo": "O seu pagamento IZI Pay foi recebido."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Envio SMS para lista aceite.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmsSendResult"
                },
                "example": {
                  "batchId": "sms-batch-125",
                  "totalDestinatarios": 25,
                  "estado": "Accepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/ListarSmsEnviadas": {
      "get": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Listar SMS enviados",
        "description": "Método e rota: `GET /api/Envio/ListarSmsEnviadas`. Retorna um histórico paginado de SMS enviados pelo comerciante autenticado.",
        "operationId": "listSentSms",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PageNumber"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "Histórico paginado de SMS enviados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SentSmsPage"
                },
                "example": {
                  "items": [
                    {
                      "smsId": 9001,
                      "telefone": "923000000",
                      "conteudo": "O seu pagamento IZI Pay foi recebido.",
                      "estado": "Sent",
                      "enviadoEm": "2026-06-14T10:30:00Z"
                    }
                  ],
                  "pageNumber": 1,
                  "pageSize": 20,
                  "totalCount": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/ObterUltimos5SmsEnviados": {
      "get": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Obter os últimos cinco SMS enviados",
        "description": "Método e rota: `GET /api/Envio/ObterUltimos5SmsEnviados`. Retorna as cinco mensagens SMS mais recentes enviadas pelo comerciante autenticado.",
        "operationId": "getLatestSentSms",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Mensagens SMS mais recentes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "maxItems": 5,
                  "items": {
                    "$ref": "#/components/schemas/SentSms"
                  }
                },
                "example": [
                  {
                    "smsId": 9001,
                    "telefone": "923000000",
                    "conteudo": "O seu pagamento IZI Pay foi recebido.",
                    "estado": "Sent",
                    "enviadoEm": "2026-06-14T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/PesquisarSMSEnviados": {
      "get": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Pesquisar SMS enviados por data",
        "description": "Método e rota: `GET /api/Envio/PesquisarSMSEnviados`. Pesquisa SMS enviados num dia, mês e ano específicos.",
        "operationId": "searchSentSmsByDate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Day"
          },
          {
            "$ref": "#/components/parameters/Month"
          },
          {
            "$ref": "#/components/parameters/Year"
          }
        ],
        "responses": {
          "200": {
            "description": "SMS enviados encontrados.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SentSms"
                  }
                },
                "example": [
                  {
                    "smsId": 9001,
                    "telefone": "923000000",
                    "conteudo": "O seu pagamento IZI Pay foi recebido.",
                    "estado": "Sent",
                    "enviadoEm": "2026-06-14T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/Envio/pesquisarEnviosPorIntervaloDeDatas": {
      "get": {
        "tags": [
          "Envio SMS"
        ],
        "summary": "Pesquisar SMS enviados por intervalo de datas",
        "description": "Método e rota: `GET /api/Envio/pesquisarEnviosPorIntervaloDeDatas`. Pesquisa SMS enviados entre uma data inicial e uma data final.",
        "operationId": "searchSentSmsByDateInterval",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StartDay"
          },
          {
            "$ref": "#/components/parameters/StartMonth"
          },
          {
            "$ref": "#/components/parameters/StartYear"
          },
          {
            "$ref": "#/components/parameters/EndDay"
          },
          {
            "$ref": "#/components/parameters/EndMonth"
          },
          {
            "$ref": "#/components/parameters/EndYear"
          }
        ],
        "responses": {
          "200": {
            "description": "SMS enviados encontrados.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SentSms"
                  }
                },
                "example": [
                  {
                    "smsId": 9001,
                    "telefone": "923000000",
                    "conteudo": "O seu pagamento IZI Pay foi recebido.",
                    "estado": "Sent",
                    "enviadoEm": "2026-06-14T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/EnvioAgendado/agendar-envio-smstexto": {
      "post": {
        "tags": [
          "SMS Agendado"
        ],
        "summary": "Agendar SMS de texto",
        "description": "Método e rota: `POST /api/EnvioAgendado/agendar-envio-smstexto`. Agenda um SMS de texto para uma data e hora futuras.",
        "operationId": "scheduleSmsText",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleSmsTextRequest"
              },
              "example": {
                "numerosDestino": [
                  "923000000"
                ],
                "conteudo": "Lembrete IZI Pay agendado.",
                "dia": 15,
                "mes": 6,
                "ano": 2026,
                "hora": 10,
                "minuto": 30
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SMS agendado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledSms"
                },
                "example": {
                  "agendamentoId": 501,
                  "estado": "Scheduled",
                  "agendadoPara": "2026-06-15T10:30:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/EnvioAgendado/listar": {
      "get": {
        "tags": [
          "SMS Agendado"
        ],
        "summary": "Listar SMS agendados",
        "description": "Método e rota: `GET /api/EnvioAgendado/listar`. Retorna mensagens SMS agendadas. Use `apenasPendentes=true` para apresentar apenas agendamentos pendentes.",
        "operationId": "listScheduledSms",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PageNumber"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "apenasPendentes",
            "in": "query",
            "required": false,
            "description": "Quando true, retorna apenas envios agendados pendentes.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mensagens SMS agendadas paginadas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledSmsPage"
                },
                "example": {
                  "items": [
                    {
                      "agendamentoId": 501,
                      "estado": "Scheduled",
                      "agendadoPara": "2026-06-15T10:30:00Z"
                    }
                  ],
                  "pageNumber": 1,
                  "pageSize": 20,
                  "totalCount": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "webhooks": {
    "pprReferencePaymentNotification": {
      "post": {
        "summary": "Notificação de pagamento de referência PPR",
        "description": "**Endpoint de Callback do Comerciante**\n\nO endpoint de callback é um URL HTTPS hospedado pelo comerciante e fornecido à equipa de desenvolvimento da IZI Pay durante a configuração. Este é o endpoint para onde a IZI Pay envia atualizações de estado do pagamento e notificações.\n\nJuntamente com o URL de callback, o comerciante também deve fornecer um Access-Key. A IZI Pay inclui esta chave nos cabeçalhos de todos os pedidos de callback para que o comerciante possa autenticar e validar as notificações recebidas.\n\n> O comerciante é responsável por garantir que o endpoint de callback está publicamente acessível e é capaz de receber e processar pedidos da IZI Pay.\n\nEste callback aplica-se a referências PPR criadas através da API atual.\n\n> **Resumo**\n>\n> Durante o onboarding, o comerciante deve fornecer os seguintes dados à equipa de desenvolvimento da IZI Pay:\n>\n> - **Callback URL:** O endpoint HTTPS para onde a IZI Pay enviará notificações de estado do pagamento.\n> - **Access-Key:** Um valor secreto escolhido e fornecido pelo comerciante. A IZI Pay inclui este valor nos cabeçalhos de todos os pedidos de callback, permitindo ao comerciante verificar que a notificação teve origem na IZI Pay.\n",
        "operationId": "receivePprReferencePaymentNotification",
        "parameters": [
          {
            "name": "Access-Key",
            "in": "header",
            "required": true,
            "description": "Chave de acesso escolhida ou gerada pelo comerciante para este webhook. A IZI Pay envia este mesmo valor no cabeçalho Access-Key para que o seu endpoint possa autenticar a notificação.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantPprWebhookRequest"
              },
              "example": {
                "idTransacao": "00000",
                "numLogSistema": "12967628",
                "idLogSistema": "8588",
                "dataTransaccaoCliente": "2026-06-08T11:52:56",
                "montantePago": 20,
                "tipoTerminal": "M",
                "iIdentTerminal": "0000000000",
                "localidadeTerminal": "Internet ",
                "refPagamento": "744757420",
                "nib": null,
                "banco": null,
                "Id": "f6701cf7-7fb8-4321-b4a1-eb5138ec9f88"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devolva HTTP 2xx com `Success: true` quando a notificação for processada com sucesso ou já tiver sido processada antes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantWebhookResponse"
                },
                "examples": {
                  "processed": {
                    "summary": "Pagamento processado",
                    "value": {
                      "Success": true,
                      "Obs": "Pagamento processado com sucesso",
                      "Id": "merchant-payment-123"
                    }
                  },
                  "duplicate": {
                    "summary": "Pagamento já processado",
                    "value": {
                      "Success": true,
                      "Obs": "Pagamento já processado",
                      "Id": "merchant-payment-123"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "qrCodePaymentNotification": {
      "post": {
        "summary": "Notificação de pagamento QR Code",
        "description": "**Endpoint de Callback do Comerciante**\n\nO endpoint de callback é um URL HTTPS hospedado pelo comerciante e fornecido à equipa de desenvolvimento da IZI Pay durante a configuração. Este é o endpoint para onde a IZI Pay envia atualizações de estado do pagamento e notificações.\n\nJuntamente com o URL de callback, o comerciante também deve fornecer um Access-Key. A IZI Pay inclui esta chave nos cabeçalhos de todos os pedidos de callback para que o comerciante possa autenticar e validar as notificações recebidas.\n\n> O comerciante é responsável por garantir que o endpoint de callback está publicamente acessível e é capaz de receber e processar pedidos da IZI Pay.\n\nEste callback aplica-se a pagamentos GPO QR Code criados através da API de Pagamentos.\n\n> **Resumo**\n>\n> Durante o onboarding, o comerciante deve fornecer os seguintes dados à equipa de desenvolvimento da IZI Pay:\n>\n> - **Callback URL:** O endpoint HTTPS para onde a IZI Pay enviará notificações de estado do pagamento.\n> - **Access-Key:** Um valor secreto escolhido e fornecido pelo comerciante. A IZI Pay inclui este valor nos cabeçalhos de todos os pedidos de callback, permitindo ao comerciante verificar que a notificação teve origem na IZI Pay.\n",
        "operationId": "receiveQrCodePaymentNotification",
        "parameters": [
          {
            "name": "Access-Key",
            "in": "header",
            "required": true,
            "description": "Chave de acesso escolhida ou gerada pelo comerciante para este webhook. A IZI Pay envia este mesmo valor no cabeçalho Access-Key para que o seu endpoint possa autenticar a notificação.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantQrCodeWebhookRequest"
              },
              "example": {
                "creationDate": "2026-06-08T17:26:45.453+01:00",
                "updatedDate": "2026-06-08T17:26:46.269+01:00",
                "id": "5CJ2IZ48T7MAPH1G",
                "amount": 1,
                "clearingPeriod": "4",
                "transactionNumber": "15",
                "status": "ACCEPTED",
                "transactionType": "PAYMENT",
                "orderOrigin": "QR_CODE",
                "currency": "AOA",
                "reference": {
                  "id": "TK050B02NWY9EKU"
                },
                "pointOfSale": {
                  "id": "540128"
                },
                "merchantReferenceNumber": "TK050B02NWY9EKU"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Devolva HTTP 2xx com `Success: true` quando a notificação for processada com sucesso ou já tiver sido processada antes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantWebhookResponse"
                },
                "examples": {
                  "processed": {
                    "summary": "Pagamento processado",
                    "value": {
                      "Success": true,
                      "Obs": "Pagamento processado com sucesso",
                      "Id": "merchant-payment-123"
                    }
                  },
                  "duplicate": {
                    "summary": "Pagamento já processado",
                    "value": {
                      "Success": true,
                      "Obs": "Pagamento já processado",
                      "Id": "merchant-payment-123"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "parameters": {
      "MerchantId": {
        "name": "merchantId",
        "in": "path",
        "required": true,
        "description": "Merchant identifier.",
        "schema": {
          "type": "string"
        },
        "example": "BB1376D9-03D3-45C6-82FA-61F4270D27B6"
      },
      "UserId": {
        "name": "userId",
        "in": "path",
        "required": true,
        "description": "User identifier.",
        "schema": {
          "type": "string"
        },
        "example": "11111111-1111-1111-1111-111111111111"
      },
      "InvoiceId": {
        "name": "invoiceId",
        "in": "path",
        "required": true,
        "description": "Invoice identifier.",
        "schema": {
          "type": "string"
        },
        "example": "inv_12345"
      },
      "PaymentId": {
        "name": "paymentId",
        "in": "path",
        "required": true,
        "description": "External payment identifier.",
        "schema": {
          "type": "string"
        },
        "example": "pay_12345"
      },
      "InternalPaymentId": {
        "name": "internalPaymentId",
        "in": "path",
        "required": true,
        "description": "Internal payment GUID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "a18aa875-7a13-47d3-96ca-795ce9ffafa9"
      },
      "PprReference": {
        "name": "pprReference",
        "in": "path",
        "required": true,
        "description": "PPR reference value.",
        "schema": {
          "type": "string"
        },
        "example": "425882116"
      },
      "PosId": {
        "name": "posId",
        "in": "path",
        "required": true,
        "description": "GPO POS terminal identifier.",
        "schema": {
          "type": "string"
        },
        "example": "413205"
      },
      "SupervisorId": {
        "name": "supervisorId",
        "in": "query",
        "required": false,
        "description": "Optional supervisor identifier for terminal operations.",
        "schema": {
          "type": "string"
        },
        "example": "12345"
      },
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "Page number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "PageSize": {
        "name": "pageSize",
        "in": "query",
        "required": false,
        "description": "Number of records per page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 20
        }
      },
      "PageNumber": {
        "name": "pageNumber",
        "in": "query",
        "required": false,
        "description": "Page number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "SmsTemplateId": {
        "name": "templateId",
        "in": "path",
        "required": true,
        "description": "SMS template identifier.",
        "schema": {
          "type": "integer"
        },
        "example": 42
      },
      "SmsContactId": {
        "name": "contactoId",
        "in": "path",
        "required": true,
        "description": "SMS contact identifier.",
        "schema": {
          "type": "integer"
        },
        "example": 120
      },
      "SmsContactListId": {
        "name": "listaId",
        "in": "path",
        "required": true,
        "description": "SMS contact list identifier.",
        "schema": {
          "type": "integer"
        },
        "example": 30
      },
      "Day": {
        "name": "dia",
        "in": "query",
        "required": true,
        "description": "Day of month.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 31
        },
        "example": 14
      },
      "Month": {
        "name": "mes",
        "in": "query",
        "required": true,
        "description": "Month number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 12
        },
        "example": 6
      },
      "Year": {
        "name": "ano",
        "in": "query",
        "required": true,
        "description": "Four-digit year.",
        "schema": {
          "type": "integer",
          "minimum": 2000
        },
        "example": 2026
      },
      "StartDay": {
        "name": "diaInicio",
        "in": "query",
        "required": true,
        "description": "Start day of month.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 31
        },
        "example": 1
      },
      "StartMonth": {
        "name": "mesInicio",
        "in": "query",
        "required": true,
        "description": "Start month number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 12
        },
        "example": 6
      },
      "StartYear": {
        "name": "anoInicio",
        "in": "query",
        "required": true,
        "description": "Start year.",
        "schema": {
          "type": "integer",
          "minimum": 2000
        },
        "example": 2026
      },
      "EndDay": {
        "name": "diaFim",
        "in": "query",
        "required": true,
        "description": "End day of month.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 31
        },
        "example": 14
      },
      "EndMonth": {
        "name": "mesFim",
        "in": "query",
        "required": true,
        "description": "End month number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 12
        },
        "example": 6
      },
      "EndYear": {
        "name": "anoFim",
        "in": "query",
        "required": true,
        "description": "End year.",
        "schema": {
          "type": "integer",
          "minimum": 2000
        },
        "example": 2026
      }
    },
    "schemas": {
      "ClientCredentialsTokenRequest": {
        "type": "object",
        "required": [
          "grant_type",
          "client_id",
          "client_secret",
          "scope"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": [
              "client_credentials"
            ]
          },
          "client_id": {
            "type": "string"
          },
          "client_secret": {
            "type": "string",
            "format": "password"
          },
          "scope": {
            "type": "string"
          }
        }
      },
      "PasswordTokenRequest": {
        "type": "object",
        "required": [
          "grant_type",
          "username",
          "password",
          "scope",
          "client_id"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": [
              "password"
            ]
          },
          "username": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "format": "password"
          },
          "scope": {
            "type": "string"
          },
          "client_id": {
            "type": "string"
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer"
          },
          "token_type": {
            "type": "string",
            "example": "Bearer"
          }
        }
      },
      "RegisterUserRequest": {
        "type": "object",
        "required": [
          "email",
          "password",
          "firstName",
          "lastName"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "format": "password"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "phoneNumber": {
            "type": "string"
          }
        }
      },
      "TokenOnlyRequest": {
        "type": "object",
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string"
          }
        }
      },
      "ForgotPasswordRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "ResetPasswordRequest": {
        "type": "object",
        "required": [
          "token",
          "newPassword"
        ],
        "properties": {
          "token": {
            "type": "string"
          },
          "newPassword": {
            "type": "string",
            "format": "password"
          }
        }
      },
      "UserInfoResponse": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "sub": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "EnableMfaRequest": {
        "type": "object",
        "required": [
          "method"
        ],
        "properties": {
          "method": {
            "type": "integer",
            "description": "MFA method identifier."
          }
        }
      },
      "AddMerchantUserRequest": {
        "type": "object",
        "required": [
          "email",
          "roleId"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "roleId": {
            "type": "string"
          }
        }
      },
      "CustomMetadata": {
        "type": "object",
        "additionalProperties": true,
        "description": "Objeto JSON definido pelo comerciante para associar um pagamento IZI Pay aos registos dos seus próprios sistemas.\n\nOs nomes das propriedades são escolhidos pelo comerciante; as chaves do exemplo são ilustrativas e não constituem uma lista fixa. Cada propriedade pode conter uma string, número, booleano, array, objeto aninhado ou `null`. A escrita e a capitalização das chaves são preservadas.\n\nA IZI Pay guarda estes valores sem os utilizar para controlar o processamento do pagamento. São devolvidos como `customMetadata` nas respostas de criação, detalhe e listagem de pagamentos e referências PPR.\n\nUtilize este objeto para identificadores internos, como números de fatura, ordens de compra, departamentos, códigos de cliente ou referências do sistema de origem. Não inclua palavras-passe, tokens de acesso, dados de cartão ou outros segredos.",
        "example": {
          "invoiceNumber": "INV-2026-0042",
          "department": "SALES",
          "sourceSystem": "ERP"
        }
      },
      "CreatePaymentRequest": {
        "type": "object",
        "required": [
          "amount",
          "currency",
          "paymentType"
        ],
        "additionalProperties": true,
        "properties": {
          "amount": {
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montante do pagamento expresso na moeda selecionada. São suportados valores decimais.\n\nPara `GPO` e `PPR` com `metadata.referenceType: Dynamic`, o montante deve estar entre `0.01` e `10.000.000`. Numa referência `PPR` do tipo `Charging`, utilize `0` para um montante aberto, introduzido pelo cliente no momento do pagamento; também é aceite um montante positivo. Valores negativos nunca são permitidos."
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "pattern": "^[A-Z]{3}$",
            "description": "Código de moeda de três letras maiúsculas, no formato ISO. Utilize `AOA` para pagamentos em kwanzas.",
            "example": "AOA"
          },
          "paymentType": {
            "type": "string",
            "description": "Meio de pagamento a utilizar. `GPO` cria um pagamento mobile money, uma autorização ou um QR Code; `PPR` cria uma referência de pagamento.",
            "enum": [
              "GPO",
              "PPR"
            ]
          },
          "reference": {
            "type": "string",
            "maxLength": 15,
            "description": "Identificador de pagamento definido pelo comerciante. É obrigatório para `GPO` e pode ter até 15 caracteres (cada método GPO pode impor um formato mais restrito).\n\nPara `PPR`, omita o campo ou envie uma string vazia para que a IZI Pay gere uma referência de 9 dígitos. Para definir a referência, envie apenas dígitos e utilize entre 9 e 15 dígitos. Uma referência dinâmica definida pelo comerciante não pode ser reutilizada enquanto a mesma referência estiver ativa e não paga para a entidade."
          },
          "description": {
            "type": "string",
            "deprecated": true,
            "description": "Descrição de topo legada. As descrições específicas do conector são lidas de `metadata.description`; utilize esse campo em novas integrações."
          },
          "metadata": {
            "description": "Configurações específicas do tipo de pagamento para `POST /api/payments`.\n\nAs configurações do conector, como `paymentMethod`, `referenceType`, `expiryDate` e os campos do cliente, pertencem diretamente a este objeto. Os campos definidos pelo comerciante devem ser agrupados em `metadata.custom`; não coloque chaves arbitrárias do comerciante ao lado das configurações do conector.\n\nOs valores enviados em `metadata.custom` são guardados com o pagamento e devolvidos na propriedade de topo `customMetadata` nas respostas de criação e consulta. Não envie um campo `customMetadata` no topo do pedido para `/api/payments`.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/GpoPaymentMetadata"
              },
              {
                "$ref": "#/components/schemas/PprPaymentMetadata"
              }
            ]
          }
        }
      },
      "GpoPaymentMetadata": {
        "type": "object",
        "additionalProperties": true,
        "description": "Configurações utilizadas quando `paymentType` é `GPO`.",
        "properties": {
          "paymentMethod": {
            "type": "string",
            "description": "Fluxo GPO a iniciar. Utilize `webframe` para checkout alojado, `onetimepurchase` para um pagamento mobile imediato, `authorization` para reservar fundos, `capture` para concluir uma autorização anterior ou `qrcode` para criar um QR Code. Assume `webframe` quando omitido ou não reconhecido.",
            "enum": [
              "webframe",
              "onetimepurchase",
              "authorization",
              "capture",
              "qrcode"
            ]
          },
          "phoneNumber": {
            "type": "string",
            "description": "Número de telemóvel do cliente utilizado nos fluxos de pagamento mobile e autorização.",
            "example": "923000000"
          },
          "provider": {
            "type": "string",
            "description": "Operadora móvel ou provedor de pagamento utilizado na transação.",
            "example": "UNITEL"
          },
          "gpo_merchant_id": {
            "type": "string",
            "description": "Identificador GPO do comerciante atribuído no onboarding. Também pode ser obtido da configuração do comerciante autenticado."
          },
          "gpo_pos_id": {
            "type": "string",
            "description": "Identificador GPO do ponto de venda atribuído no onboarding. Também pode ser obtido da configuração do comerciante autenticado."
          },
          "qrSize": {
            "type": "string",
            "description": "Tamanho solicitado para a imagem do QR Code. Utilizado apenas quando `paymentMethod` é `qrcode`; assume `MEDIUM` quando omitido.",
            "example": "MEDIUM"
          },
          "qrType": {
            "type": "string",
            "description": "Comportamento do QR Code. Utilizado apenas quando `paymentMethod` é `qrcode`; assume `STATIC` quando omitido.",
            "example": "STATIC"
          },
          "maxTransactions": {
            "type": "integer",
            "minimum": 1,
            "description": "Número máximo de pagamentos aceites pelo QR Code. Utilizado apenas em pagamentos por QR Code e assume `1` quando omitido."
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "description": "Expiração opcional do QR Code em formato ISO 8601. Assume 24 horas após a criação quando omitida."
          },
          "authorizationId": {
            "type": "string",
            "description": "Identificador devolvido por uma autorização anterior. Obrigatório quando `paymentMethod` é `capture`."
          },
          "description": {
            "type": "string",
            "description": "Descrição enviada ao GPO. Em pagamentos por QR Code, é utilizada a `reference` de topo quando este valor é omitido."
          },
          "custom": {
            "type": "object",
            "additionalProperties": true,
            "description": "Objeto JSON opcional definido pelo comerciante para dados internos de reconciliação.\n\nO comerciante escolhe os nomes das propriedades. Os valores podem ser strings, números, booleanos, arrays, objetos aninhados ou `null`. A IZI Pay não utiliza estas propriedades para selecionar ou configurar o método de pagamento GPO.\n\nO objeto é devolvido como `customMetadata` nas respostas de detalhe e listagem de pagamentos. Não inclua credenciais, dados de cartão, tokens de acesso ou outros segredos.",
            "example": {
              "invoiceNumber": "INV-2026-0042",
              "department": "SALES",
              "sourceSystem": "ERP"
            }
          }
        }
      },
      "PprPaymentMetadata": {
        "type": "object",
        "additionalProperties": true,
        "description": "Configurações utilizadas quando `paymentType` é `PPR`.",
        "properties": {
          "referenceType": {
            "type": "string",
            "description": "Comportamento da referência PPR. `Dynamic` é uma referência de montante fixo e exige `amount` superior a zero. `Charging` é reutilizável e pode receber múltiplas transações; utilize `amount: 0` quando o pagador deve escolher o montante. Assume `Dynamic` quando omitido.",
            "default": "Dynamic",
            "enum": [
              "Dynamic",
              "Charging"
            ]
          },
          "expiryDate": {
            "type": "string",
            "format": "date-time",
            "description": "Data de expiração ISO 8601 opcional. Quando omitida, uma referência dinâmica expira um mês após a criação e uma referência charging assume o final de 2099."
          },
          "description": {
            "type": "string",
            "description": "Motivo ou designação da referência definido pelo comerciante."
          },
          "customerEmail": {
            "type": "string",
            "format": "email",
            "description": "Email opcional do cliente, guardado com a referência e devolvido na resposta do pagamento PPR."
          },
          "customerName": {
            "type": "string",
            "description": "Nome opcional do cliente, guardado com a referência e devolvido na resposta do pagamento PPR."
          },
          "customerTelephone": {
            "type": "string",
            "description": "Número de telefone opcional do cliente, devolvido na resposta do pagamento PPR."
          },
          "documentNumber": {
            "type": "string",
            "description": "Número opcional do documento de identificação do cliente, devolvido nos detalhes do pagamento."
          },
          "custom": {
            "type": "object",
            "additionalProperties": true,
            "description": "Objeto JSON opcional definido pelo comerciante para associar o pagamento PPR aos seus registos internos.\n\nO comerciante escolhe os nomes das propriedades. Os valores podem ser strings, números, booleanos, arrays, objetos aninhados ou `null`. Estes valores não afetam a entidade, referência, montante, expiração ou estado do pagamento.\n\nEnvie este objeto como `metadata.custom` ao utilizar `POST /api/payments`. A IZI Pay guarda-o e devolve-o na propriedade de topo `customMetadata` nas respostas de criação e consulta PPR. Não inclua credenciais, dados de cartão, tokens de acesso ou outros segredos.",
            "example": {
              "invoiceNumber": "INV-2026-0042",
              "department": "SALES",
              "sourceSystem": "ERP"
            }
          }
        }
      },
      "CreatePprReferenceRequest": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "reference": {
            "type": "string",
            "pattern": "^[0-9]{9,15}$",
            "description": "Referência PPR opcional, definida pelo comerciante, com 9 a 15 dígitos. Omita para gerar automaticamente."
          },
          "referenceType": {
            "type": "string",
            "description": "`Dynamic` cria uma referência de montante fixo. `Charging` cria uma referência reutilizável e permite montante aberto. Assume `Dynamic` quando omitido.",
            "default": "Dynamic",
            "enum": [
              "Dynamic",
              "Charging"
            ]
          },
          "amount": {
            "type": "number",
            "description": "Obrigatório e superior a zero para `Dynamic`; opcional para `Charging`, onde `0` representa um montante aberto."
          },
          "expiryDate": {
            "type": "string",
            "format": "date-time",
            "description": "Data futura de expiração opcional no formato ISO 8601."
          },
          "description": {
            "type": "string",
            "description": "Motivo ou designação opcional da referência, visível ao comerciante."
          },
          "customerEmail": {
            "type": "string",
            "format": "email",
            "description": "Email opcional do cliente, guardado com a referência."
          },
          "customerName": {
            "type": "string",
            "description": "Nome completo opcional do cliente, guardado com a referência."
          },
          "customerTelephone": {
            "type": "string",
            "description": "Número de telefone opcional do cliente, guardado com a referência."
          },
          "documentNumber": {
            "type": "string",
            "description": "Número opcional do documento de identificação do cliente, guardado com a referência."
          },
          "customMetadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Objeto JSON opcional definido pelo comerciante para reconciliação interna e associação de registos.\n\nEsta é a forma utilizada pelos endpoints PPR diretos: envie `customMetadata` na raiz do pedido para `POST /api/references/ppr`, `/api/references/ppr/legacy` e em cada item de `/api/references/ppr/bulk`. Não envolva este campo em `metadata` ou `custom`.\n\nOs nomes das propriedades são escolhidos pelo comerciante. Os valores podem ser strings, números, booleanos, arrays, objetos aninhados ou `null`. Os valores não afetam o processamento PPR e são devolvidos sem alteração como `customMetadata` nas respostas de criação, detalhe e listagem.\n\nNão inclua credenciais, dados de cartão, tokens de acesso ou outros segredos.",
            "example": {
              "invoiceNumber": "INV-2026-0042",
              "department": "SALES",
              "sourceSystem": "ERP",
              "purchaseOrder": "PO-98765",
              "customerCode": "CUS-001"
            }
          }
        }
      },
      "CreateBulkPprReferencesRequest": {
        "type": "object",
        "required": [
          "references"
        ],
        "properties": {
          "references": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/CreatePprReferenceRequest"
            }
          }
        }
      },
      "PaymentCreationResponse": {
        "type": "object",
        "additionalProperties": true,
        "description": "Resposta de criação do pagamento. Os campos exatos dependem do tipo e método de pagamento.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Nas respostas PPR compactas, identifica o registo da referência PPR. Utilize `reference`, e não este campo, em `GET /api/payments/{paymentId}`."
          },
          "internalId": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador interno do pagamento, quando incluído pelo fluxo selecionado."
          },
          "entity": {
            "type": "string"
          },
          "reference": {
            "type": "string",
            "description": "Referência do provedor/pagamento. Para PPR, utilize este valor para consultar os detalhes."
          },
          "amount": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "description": {
            "type": "string"
          },
          "customer": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "name": {
                "type": "string"
              },
              "telephone": {
                "type": "string"
              }
            }
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          }
        }
      },
      "PaymentDetailsResponse": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "id": {
            "type": "string"
          },
          "internalId": {
            "type": "string",
            "format": "uuid"
          },
          "merchantId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "paymentType": {
            "type": "string",
            "enum": [
              "GPO",
              "PPR"
            ]
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time"
          },
          "description": {
            "type": "string"
          },
          "customerEmail": {
            "type": "string",
            "format": "email"
          },
          "customerName": {
            "type": "string"
          },
          "customerTelephone": {
            "type": "string"
          },
          "documentNumber": {
            "type": "string"
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          }
        }
      },
      "PagedPaymentsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentDetailsResponse"
            }
          },
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "totalItems": {
            "type": "integer"
          }
        }
      },
      "PprReferenceResponse": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "referenceStatus": {
            "type": "string"
          },
          "entity": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "description": {
            "type": "string"
          },
          "customerEmail": {
            "type": "string",
            "format": "email"
          },
          "customerName": {
            "type": "string"
          },
          "customerTelephone": {
            "type": "string"
          },
          "documentNumber": {
            "type": "string"
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          }
        }
      },
      "PprReferenceListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PprReferenceResponse"
            }
          },
          "totalCount": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        }
      },
      "BulkPprReferenceResponse": {
        "type": "object",
        "properties": {
          "successCount": {
            "type": "integer"
          },
          "errorCount": {
            "type": "integer"
          },
          "references": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PprReferenceResponse"
            }
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "MerchantPprWebhookRequest": {
        "type": "object",
        "required": [
          "idTransacao",
          "numLogSistema",
          "idLogSistema",
          "dataTransaccaoCliente",
          "montantePago",
          "tipoTerminal",
          "iIdentTerminal",
          "localidadeTerminal",
          "refPagamento",
          "Id"
        ],
        "properties": {
          "idTransacao": {
            "type": "string",
            "description": "Identificador da transação."
          },
          "numLogSistema": {
            "type": "string",
            "description": "Número de log do sistema associado à notificação de pagamento."
          },
          "idLogSistema": {
            "type": "string",
            "description": "Identificador de período/log do sistema."
          },
          "dataTransaccaoCliente": {
            "type": "string",
            "format": "date-time",
            "description": "Data e hora em que o pagamento do cliente foi registado."
          },
          "montantePago": {
            "type": "number",
            "description": "Montante pago pelo cliente."
          },
          "tipoTerminal": {
            "type": "string",
            "description": "Tipo de terminal usado no pagamento."
          },
          "iIdentTerminal": {
            "type": "string",
            "description": "Identificador do terminal."
          },
          "localidadeTerminal": {
            "type": "string",
            "description": "Localidade do terminal."
          },
          "refPagamento": {
            "type": "string",
            "description": "Referência de pagamento paga pelo cliente."
          },
          "nib": {
            "type": "string",
            "nullable": true,
            "description": "NIB da conta debitada, quando disponível."
          },
          "banco": {
            "type": "string",
            "nullable": true,
            "description": "Nome do banco, quando disponível."
          },
          "Id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único da notificação. Use este valor para idempotência."
          }
        }
      },
      "MerchantQrCodeWebhookRequest": {
        "type": "object",
        "required": [
          "creationDate",
          "updatedDate",
          "id",
          "amount",
          "clearingPeriod",
          "transactionNumber",
          "status",
          "transactionType",
          "orderOrigin",
          "currency",
          "reference",
          "pointOfSale",
          "merchantReferenceNumber"
        ],
        "properties": {
          "creationDate": {
            "type": "string",
            "format": "date-time",
            "description": "Data e hora em que a transação QR Code foi criada."
          },
          "updatedDate": {
            "type": "string",
            "format": "date-time",
            "description": "Data e hora em que o estado da transação QR Code foi atualizado."
          },
          "id": {
            "type": "string",
            "description": "Identificador único da transação no provedor. Use este valor para idempotência."
          },
          "amount": {
            "type": "number",
            "description": "Montante pago pelo cliente."
          },
          "clearingPeriod": {
            "type": "string",
            "description": "Período de compensação associado à transação."
          },
          "transactionNumber": {
            "type": "string",
            "description": "Número da transação no provedor."
          },
          "status": {
            "type": "string",
            "description": "Estado do pagamento QR Code.",
            "example": "ACCEPTED"
          },
          "transactionType": {
            "type": "string",
            "description": "Tipo da transação.",
            "example": "PAYMENT"
          },
          "orderOrigin": {
            "type": "string",
            "description": "Origem da ordem de pagamento.",
            "example": "QR_CODE"
          },
          "currency": {
            "type": "string",
            "description": "Moeda do pagamento.",
            "example": "AOA"
          },
          "reference": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Identificador da referência QR Code."
              }
            }
          },
          "pointOfSale": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Identificador do ponto de venda."
              }
            }
          },
          "merchantReferenceNumber": {
            "type": "string",
            "description": "Número de referência do comerciante associado ao pagamento QR Code."
          }
        }
      },
      "MerchantWebhookResponse": {
        "type": "object",
        "required": [
          "Success",
          "Obs",
          "Id"
        ],
        "properties": {
          "Success": {
            "type": "boolean",
            "description": "Devolva true quando a notificação for processada com sucesso ou já tiver sido processada antes."
          },
          "Obs": {
            "type": "string",
            "description": "Nota curta sobre o processamento."
          },
          "Id": {
            "type": "string",
            "description": "Identificador interno do pagamento no sistema do comerciante."
          }
        }
      },
      "SmsLoggedUser": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "merchantId": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "SmsMerchant": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "merchantId": {
            "type": "string",
            "format": "uuid"
          },
          "nome": {
            "type": "string"
          },
          "remetenteSms": {
            "type": "string",
            "description": "Sender name configured for SMS messages."
          }
        }
      },
      "SmsBalance": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "merchantId": {
            "type": "string",
            "format": "uuid"
          },
          "saldoAtual": {
            "type": "integer",
            "description": "Current available SMS units."
          },
          "unidade": {
            "type": "string",
            "example": "sms"
          },
          "atualizadoEm": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SmsBalanceLedgerEntry": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "id": {
            "type": "integer"
          },
          "tipo": {
            "type": "string",
            "description": "Ledger entry type, such as credit or debit."
          },
          "quantidade": {
            "type": "integer"
          },
          "saldoDepois": {
            "type": "integer"
          },
          "descricao": {
            "type": "string"
          },
          "criadoEm": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SmsTemplateRequest": {
        "type": "object",
        "required": [
          "nome",
          "conteudo"
        ],
        "properties": {
          "nome": {
            "type": "string"
          },
          "conteudo": {
            "type": "string"
          }
        }
      },
      "SmsTemplate": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "id": {
            "type": "integer"
          },
          "nome": {
            "type": "string"
          },
          "conteudo": {
            "type": "string"
          },
          "criadoEm": {
            "type": "string",
            "format": "date-time"
          },
          "atualizadoEm": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SmsContactRequest": {
        "type": "object",
        "required": [
          "nome",
          "telefone"
        ],
        "properties": {
          "nome": {
            "type": "string"
          },
          "telefone": {
            "type": "string",
            "description": "Destination phone number in the format accepted by the SMS service."
          }
        }
      },
      "SmsContact": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "contactoId": {
            "type": "integer"
          },
          "nome": {
            "type": "string"
          },
          "telefone": {
            "type": "string"
          }
        }
      },
      "SmsContactListRequest": {
        "type": "object",
        "required": [
          "nome",
          "contactoIds"
        ],
        "properties": {
          "nome": {
            "type": "string"
          },
          "contactoIds": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        }
      },
      "SmsContactList": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "listaDeContactoId": {
            "type": "integer"
          },
          "nome": {
            "type": "string"
          },
          "contactoIds": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "contactos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SmsContact"
            }
          },
          "totalContactos": {
            "type": "integer"
          }
        }
      },
      "AddSmsContactToListRequest": {
        "type": "object",
        "required": [
          "contactoId",
          "listaId"
        ],
        "properties": {
          "contactoId": {
            "type": "integer"
          },
          "listaId": {
            "type": "integer"
          }
        }
      },
      "SendSmsTextRequest": {
        "type": "object",
        "required": [
          "numerosDestino",
          "conteudo"
        ],
        "properties": {
          "numerosDestino": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "conteudo": {
            "type": "string"
          }
        }
      },
      "SendSmsTemplateRequest": {
        "type": "object",
        "required": [
          "smsId",
          "numerosDestino"
        ],
        "properties": {
          "smsId": {
            "type": "integer",
            "description": "SMS template identifier."
          },
          "numerosDestino": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "remetente": {
            "type": "string"
          }
        }
      },
      "SendSmsListRequest": {
        "type": "object",
        "required": [
          "listaId",
          "conteudo"
        ],
        "properties": {
          "listaId": {
            "type": "integer"
          },
          "remetente": {
            "type": "string"
          },
          "conteudo": {
            "type": "string"
          }
        }
      },
      "SmsSendResult": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "batchId": {
            "type": "string"
          },
          "totalDestinatarios": {
            "type": "integer"
          },
          "estado": {
            "type": "string"
          }
        }
      },
      "SentSms": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "smsId": {
            "type": "integer"
          },
          "telefone": {
            "type": "string"
          },
          "conteudo": {
            "type": "string"
          },
          "estado": {
            "type": "string"
          },
          "enviadoEm": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ScheduleSmsTextRequest": {
        "type": "object",
        "required": [
          "numerosDestino",
          "conteudo",
          "dia",
          "mes",
          "ano",
          "hora",
          "minuto"
        ],
        "properties": {
          "numerosDestino": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "conteudo": {
            "type": "string"
          },
          "dia": {
            "type": "integer",
            "minimum": 1,
            "maximum": 31
          },
          "mes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12
          },
          "ano": {
            "type": "integer"
          },
          "hora": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23
          },
          "minuto": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59
          }
        }
      },
      "ScheduledSms": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "agendamentoId": {
            "type": "integer"
          },
          "estado": {
            "type": "string"
          },
          "agendadoPara": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SmsActionResult": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "SmsContactPage": {
        "type": "object",
        "properties": {
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SmsContact"
            }
          }
        }
      },
      "SmsContactListPage": {
        "type": "object",
        "properties": {
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SmsContactList"
            }
          }
        }
      },
      "SentSmsPage": {
        "type": "object",
        "properties": {
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SentSms"
            }
          }
        }
      },
      "ScheduledSmsPage": {
        "type": "object",
        "properties": {
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduledSms"
            }
          }
        }
      },
      "SmsPage": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "pageNumber": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "totalCount": {
            "type": "integer"
          }
        }
      },
      "TodoResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "example": "To Be Done Soon"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request could not be processed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": "To Be Done Soon",
              "message": "To Be Done Soon"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The access token is missing, invalid, or expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": "To Be Done Soon",
              "message": "To Be Done Soon"
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested resource was not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": "To Be Done Soon",
              "message": "To Be Done Soon"
            }
          }
        }
      }
    }
  }
}