{
  "openapi": "3.1.0",
  "info": {
    "title": "Authentication API",
    "version": "0.1.0",
    "description": "Manage secure access to the IZI Pay platform. This API provides endpoints for generating, validating, and refreshing authentication tokens, as well as managing Multi-Factor Authentication (MFA) to ensure the highest level of security for your integrations."
  },
  "servers": [
    {
      "url": "https://pay.izipay.ao",
      "description": "Production"
    },
    {
      "url": "https://pay-sandbox.izipay.ao",
      "description": "Sandbox"
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "Register users, verify email addresses, issue tokens, recover access, and read the signed-in user profile."
    },
    {
      "name": "MFA",
      "description": "Add or remove multi-factor authentication for a signed-in user."
    },
    {
      "name": "Merchant Access",
      "description": "Manage which users can access a merchant account."
    },
    {
      "name": "Billing",
      "description": "View merchant subscription, invoice, and usage information."
    },
    {
      "name": "Payments",
      "description": "Create, list, sync, and cancel payment operations."
    },
    {
      "name": "PPR References",
      "description": "Create and manage PPR payment references."
    },
    {
      "name": "Terminal Operations",
      "description": "Open, close, and inspect GPO terminal status."
    },
    {
      "name": "SMS Account",
      "description": "Read the signed-in SMS user and merchant sender configuration."
    },
    {
      "name": "SMS Balance",
      "description": "View SMS balance and balance ledger history for the merchant account."
    },
    {
      "name": "SMS Templates",
      "description": "Create and manage reusable SMS message templates."
    },
    {
      "name": "SMS Contacts",
      "description": "Manage SMS contacts and contact lists for bulk sends."
    },
    {
      "name": "SMS Sending",
      "description": "Send SMS messages and inspect sent message history."
    },
    {
      "name": "Scheduled SMS",
      "description": "Schedule SMS messages and list pending or historical scheduled sends."
    }
  ],
  "paths": {
    "/api/auth/register": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Register a user",
        "description": "Method and route: `POST /api/auth/register`. Creates a new user account in IZI Pay Identity. Use it at the start of the onboarding flow, then guide the user through email verification before they rely on the account for protected operations.",
        "operationId": "registerUser",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterUserRequest"
              },
              "example": {
                "email": "test.user@example.com",
                "password": "TestPassword123!",
                "firstName": "Test",
                "lastName": "User",
                "phoneNumber": "900000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User registration accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/api/auth/verify-email": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify an email address",
        "description": "Method and route: `POST /api/auth/verify-email`. Confirms that the user controls the email address used during registration. Send the verification token exactly as received from the email verification flow.",
        "operationId": "verifyEmail",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenOnlyRequest"
              },
              "example": {
                "token": "test-email-verification-token"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email verified.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/connect/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get an access token",
        "description": "Method and route: `POST /connect/token`. Use this endpoint when an app or user needs an access token. The same route supports client credentials for server-to-server calls and password login for trusted user login flows.",
        "operationId": "getToken",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ClientCredentialsTokenRequest"
                  },
                  {
                    "$ref": "#/components/schemas/PasswordTokenRequest"
                  }
                ]
              },
              "examples": {
                "clientCredentials": {
                  "summary": "Client app token",
                  "value": {
                    "grant_type": "client_credentials",
                    "client_id": "test-client-id",
                    "client_secret": "test-client-secret",
                    "scope": "izi-api"
                  }
                },
                "passwordLogin": {
                  "summary": "User login token",
                  "value": {
                    "grant_type": "password",
                    "username": "test.user@example.com",
                    "password": "TestPassword123!",
                    "scope": "openid profile email izi-api offline_access",
                    "client_id": "password-client"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token issued successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                },
                "examples": {
                  "clientCredentials": {
                    "summary": "Client credentials response",
                    "value": {
                      "access_token": "To Be Done Soon",
                      "expires_in": 3600,
                      "token_type": "Bearer"
                    }
                  },
                  "passwordLogin": {
                    "summary": "Password login response",
                    "value": {
                      "access_token": "To Be Done Soon",
                      "refresh_token": "To Be Done Soon",
                      "expires_in": 3600,
                      "token_type": "Bearer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/connect/userinfo": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get user info",
        "description": "Method and route: `GET /connect/userinfo`. Returns profile claims for the user represented by the bearer token. This is useful after login when an application needs the user's identity details without storing them locally.",
        "operationId": "getUserInfo",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "User profile claims.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfoResponse"
                },
                "example": {
                  "sub": "To Be Done Soon",
                  "email": "To Be Done Soon",
                  "name": "To Be Done Soon"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/auth/forgot-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Start password reset",
        "description": "Method and route: `POST /api/auth/forgot-password`. Starts the password reset process for a user who cannot sign in. If the email is known, the user should receive a reset token through the configured recovery channel.",
        "operationId": "forgotPassword",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForgotPasswordRequest"
              },
              "example": {
                "email": "test.user@example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset flow started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/api/auth/reset-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Reset password",
        "description": "Method and route: `POST /api/auth/reset-password`. Completes the recovery flow by exchanging a valid reset token for a new password. Treat reset tokens as short-lived secrets and never log them.",
        "operationId": "resetPassword",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              },
              "example": {
                "token": "test-password-reset-token",
                "newPassword": "NewTestPassword123!"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset completed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/api/auth/mfa/enable": {
      "post": {
        "tags": [
          "MFA"
        ],
        "summary": "Enable MFA",
        "description": "Method and route: `POST /api/auth/mfa/enable`. Turns on multi-factor authentication for the signed-in user. The `method` value identifies which MFA method the user wants to enable.",
        "operationId": "enableMfa",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnableMfaRequest"
              },
              "example": {
                "method": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "MFA enabled or setup started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/auth/mfa/disable": {
      "post": {
        "tags": [
          "MFA"
        ],
        "summary": "Disable MFA",
        "description": "Method and route: `POST /api/auth/mfa/disable`. Removes multi-factor authentication from the signed-in user's account. Use this only after you have confirmed the user's intent inside your own product experience.",
        "operationId": "disableMfa",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "MFA disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TodoResponse"
                },
                "example": {
                  "message": "To Be Done Soon"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "webhooks": {
    "pprReferencePaymentNotification": {
      "post": {
        "summary": "PPR reference payment notification",
        "description": "**Merchant Callback Endpoint**\n\nThe callback endpoint is an HTTPS URL hosted by the merchant and provided to the IZI Pay development team during setup. This is the endpoint where IZI Pay sends payment status updates and notifications.\n\nAlong with the callback URL, the merchant must also provide an Access-Key. IZI Pay includes this key in the request headers of every callback request so that the merchant can authenticate and validate incoming notifications.\n\n> The merchant is responsible for ensuring that the callback endpoint is publicly accessible and capable of receiving and processing requests from IZI Pay.\n\nThis callback applies to PPR references created through the current API.\n\n> **Summary**\n>\n> During onboarding, the merchant must provide the following details to the IZI Pay development team:\n>\n> - **Callback URL:** The HTTPS endpoint where IZI Pay will send payment status notifications.\n> - **Access-Key:** A secret value chosen and provided by the merchant. IZI Pay includes this value in the request headers of every callback request, allowing the merchant to verify that the notification originated from IZI Pay.\n",
        "operationId": "receivePprReferencePaymentNotification",
        "parameters": [
          {
            "name": "Access-Key",
            "in": "header",
            "required": true,
            "description": "Access key chosen or generated by the merchant for this webhook. IZI Pay sends this same value in the Access-Key header so your endpoint can authenticate the notification.",
            "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": "Return HTTP 2xx with `Success: true` when the notification was processed successfully or was already processed before.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantWebhookResponse"
                },
                "examples": {
                  "processed": {
                    "summary": "Payment processed",
                    "value": {
                      "Success": true,
                      "Obs": "Payment processed successfully",
                      "Id": "merchant-payment-123"
                    }
                  },
                  "duplicate": {
                    "summary": "Payment already processed",
                    "value": {
                      "Success": true,
                      "Obs": "Payment already processed",
                      "Id": "merchant-payment-123"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "qrCodePaymentNotification": {
      "post": {
        "summary": "QR Code payment notification",
        "description": "**Merchant Callback Endpoint**\n\nThe callback endpoint is an HTTPS URL hosted by the merchant and provided to the IZI Pay development team during setup. This is the endpoint where IZI Pay sends payment status updates and notifications.\n\nAlong with the callback URL, the merchant must also provide an Access-Key. IZI Pay includes this key in the request headers of every callback request so that the merchant can authenticate and validate incoming notifications.\n\n> The merchant is responsible for ensuring that the callback endpoint is publicly accessible and capable of receiving and processing requests from IZI Pay.\n\nThis callback applies to GPO QR Code payments created through the Payments API.\n\n> **Summary**\n>\n> During onboarding, the merchant must provide the following details to the IZI Pay development team:\n>\n> - **Callback URL:** The HTTPS endpoint where IZI Pay will send payment status notifications.\n> - **Access-Key:** A secret value chosen and provided by the merchant. IZI Pay includes this value in the request headers of every callback request, allowing the merchant to verify that the notification originated from IZI Pay.\n",
        "operationId": "receiveQrCodePaymentNotification",
        "parameters": [
          {
            "name": "Access-Key",
            "in": "header",
            "required": true,
            "description": "Access key chosen or generated by the merchant for this webhook. IZI Pay sends this same value in the Access-Key header so your endpoint can authenticate the notification.",
            "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": "Return HTTP 2xx with `Success: true` when the notification was processed successfully or was already processed before.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantWebhookResponse"
                },
                "examples": {
                  "processed": {
                    "summary": "Payment processed",
                    "value": {
                      "Success": true,
                      "Obs": "Payment processed successfully",
                      "Id": "merchant-payment-123"
                    }
                  },
                  "duplicate": {
                    "summary": "Payment already processed",
                    "value": {
                      "Success": true,
                      "Obs": "Payment already processed",
                      "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": "A merchant-defined JSON object for linking an IZI Pay payment to records in your own systems.\n\nProperty names are chosen by the merchant; the example keys are illustrative and are not a fixed list. Each property may contain a JSON string, number, boolean, array, nested object, or `null`. Key spelling and casing are preserved.\n\nIZI Pay stores these values without using them to control payment processing. They are returned as `customMetadata` by payment creation/detail/list and PPR creation/detail/list responses.\n\nUse this object for internal identifiers such as invoice numbers, purchase orders, departments, customer codes, or source-system references. Do not include passwords, access tokens, card details, or other secrets.",
        "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": "Payment amount expressed in the selected currency. Decimals are supported.\n\nFor `GPO` and `PPR` with `metadata.referenceType: Dynamic`, the amount must be between `0.01` and `10,000,000`. For a `PPR` charging reference, use `0` for an open amount that the customer enters when paying; a positive amount is also accepted. Negative values are never allowed."
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "pattern": "^[A-Z]{3}$",
            "description": "Three-letter uppercase ISO-style currency code. Use `AOA` for kwanza payments.",
            "example": "AOA"
          },
          "paymentType": {
            "type": "string",
            "description": "Payment rail to use. `GPO` creates a mobile money, authorization, or QR Code payment; `PPR` creates a payment reference.",
            "enum": [
              "GPO",
              "PPR"
            ]
          },
          "reference": {
            "type": "string",
            "maxLength": 15,
            "description": "Merchant payment identifier. It is required for `GPO` and may contain up to 15 characters (individual GPO methods can impose a stricter format).\n\nFor `PPR`, omit it or send an empty string to have IZI Pay generate a 9-digit reference. To define the reference yourself, send only digits and use between 9 and 15 digits. A merchant-defined dynamic reference cannot be reused while the same reference is active and unpaid for the entity."
          },
          "description": {
            "type": "string",
            "deprecated": true,
            "description": "Legacy top-level description. Connector-specific descriptions are read from `metadata.description`; use that field for new integrations."
          },
          "metadata": {
            "description": "Payment-type-specific settings for `POST /api/payments`.\n\nConnector settings such as `paymentMethod`, `referenceType`, `expiryDate`, and customer fields belong directly in this object. Merchant-defined fields must be grouped inside `metadata.custom`; do not place arbitrary merchant keys alongside connector settings.\n\nValues sent in `metadata.custom` are stored with the payment and returned as the top-level `customMetadata` property in creation and lookup responses. Do not send a top-level `customMetadata` field to `/api/payments`.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/GpoPaymentMetadata"
              },
              {
                "$ref": "#/components/schemas/PprPaymentMetadata"
              }
            ]
          }
        }
      },
      "GpoPaymentMetadata": {
        "type": "object",
        "additionalProperties": true,
        "description": "Settings used when `paymentType` is `GPO`.",
        "properties": {
          "paymentMethod": {
            "type": "string",
            "description": "GPO flow to start. Use `webframe` for hosted checkout, `onetimepurchase` for an immediate mobile payment, `authorization` to reserve funds, `capture` to complete a previous authorization, or `qrcode` to create a QR Code. Defaults to `webframe` when omitted or unrecognized.",
            "enum": [
              "webframe",
              "onetimepurchase",
              "authorization",
              "capture",
              "qrcode"
            ]
          },
          "phoneNumber": {
            "type": "string",
            "description": "Customer mobile number used by mobile payment and authorization flows.",
            "example": "923000000"
          },
          "provider": {
            "type": "string",
            "description": "Mobile network/payment provider used for the transaction.",
            "example": "UNITEL"
          },
          "gpo_merchant_id": {
            "type": "string",
            "description": "GPO merchant identifier assigned during onboarding. It can also be supplied by the authenticated merchant configuration."
          },
          "gpo_pos_id": {
            "type": "string",
            "description": "GPO point-of-sale identifier assigned during onboarding. It can also be supplied by the authenticated merchant configuration."
          },
          "qrSize": {
            "type": "string",
            "description": "Requested QR Code image size. Used only when `paymentMethod` is `qrcode`; defaults to `MEDIUM`.",
            "example": "MEDIUM"
          },
          "qrType": {
            "type": "string",
            "description": "QR Code behavior. Used only when `paymentMethod` is `qrcode`; defaults to `STATIC`.",
            "example": "STATIC"
          },
          "maxTransactions": {
            "type": "integer",
            "minimum": 1,
            "description": "Maximum number of payments accepted by the QR Code. Used only for QR Code payments and defaults to `1`."
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "description": "Optional QR Code expiry in ISO 8601 format. Defaults to 24 hours after creation."
          },
          "authorizationId": {
            "type": "string",
            "description": "Identifier returned by a previous authorization. Required when `paymentMethod` is `capture`."
          },
          "description": {
            "type": "string",
            "description": "Description sent to GPO. For QR Code payments, the top-level `reference` is used when this value is omitted."
          },
          "custom": {
            "type": "object",
            "additionalProperties": true,
            "description": "Optional merchant-defined JSON object for internal reconciliation data.\n\nThe merchant chooses the property names. Values may be strings, numbers, booleans, arrays, nested objects, or `null`. IZI Pay does not use these properties to select or configure the GPO payment method.\n\nThe object is returned as `customMetadata` in payment detail and list responses. Do not include credentials, card details, access tokens, or other secrets.",
            "example": {
              "invoiceNumber": "INV-2026-0042",
              "department": "SALES",
              "sourceSystem": "ERP"
            }
          }
        }
      },
      "PprPaymentMetadata": {
        "type": "object",
        "additionalProperties": true,
        "description": "Settings used when `paymentType` is `PPR`.",
        "properties": {
          "referenceType": {
            "type": "string",
            "description": "PPR reference behavior. `Dynamic` is a fixed-amount reference and requires `amount` greater than zero. `Charging` is reusable and can receive multiple transactions; use `amount: 0` when the payer should choose the amount. Defaults to `Dynamic` when omitted.",
            "default": "Dynamic",
            "enum": [
              "Dynamic",
              "Charging"
            ]
          },
          "expiryDate": {
            "type": "string",
            "format": "date-time",
            "description": "Optional ISO 8601 expiry date. If omitted, a dynamic reference expires one month after creation and a charging reference defaults to the end of 2099."
          },
          "description": {
            "type": "string",
            "description": "Merchant-facing reason or label for the reference."
          },
          "customerEmail": {
            "type": "string",
            "format": "email",
            "description": "Optional customer email stored with the reference and returned in the PPR payment response."
          },
          "customerName": {
            "type": "string",
            "description": "Optional customer name stored with the reference and returned in the PPR payment response."
          },
          "customerTelephone": {
            "type": "string",
            "description": "Optional customer telephone number returned in the PPR payment response."
          },
          "documentNumber": {
            "type": "string",
            "description": "Optional customer identity document number returned in payment details."
          },
          "custom": {
            "type": "object",
            "additionalProperties": true,
            "description": "Optional merchant-defined JSON object for linking the PPR payment to your internal records.\n\nThe merchant chooses the property names. Values may be strings, numbers, booleans, arrays, nested objects, or `null`. These values do not affect the generated entity, reference, amount, expiry, or payment status.\n\nSend this object as `metadata.custom` when using `POST /api/payments`. IZI Pay stores it and returns it as the top-level `customMetadata` property in PPR creation and lookup responses. Do not include credentials, card details, access tokens, or other secrets.",
            "example": {
              "invoiceNumber": "INV-2026-0042",
              "department": "SALES",
              "sourceSystem": "ERP"
            }
          }
        }
      },
      "CreatePprReferenceRequest": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "reference": {
            "type": "string",
            "pattern": "^[0-9]{9,15}$",
            "description": "Optional merchant-defined PPR reference containing 9 to 15 digits. Omit it to generate the reference automatically."
          },
          "referenceType": {
            "type": "string",
            "description": "`Dynamic` creates a fixed-amount reference. `Charging` creates a reusable reference and allows an open amount. Defaults to `Dynamic` when omitted.",
            "default": "Dynamic",
            "enum": [
              "Dynamic",
              "Charging"
            ]
          },
          "amount": {
            "type": "number",
            "description": "Required and greater than zero for `Dynamic`; optional for `Charging`, where `0` represents an open amount."
          },
          "expiryDate": {
            "type": "string",
            "format": "date-time",
            "description": "Optional future expiry in ISO 8601 format."
          },
          "description": {
            "type": "string",
            "description": "Optional merchant-facing reason or label for the reference."
          },
          "customerEmail": {
            "type": "string",
            "format": "email",
            "description": "Optional customer email stored with the reference."
          },
          "customerName": {
            "type": "string",
            "description": "Optional customer full name stored with the reference."
          },
          "customerTelephone": {
            "type": "string",
            "description": "Optional customer telephone number stored with the reference."
          },
          "documentNumber": {
            "type": "string",
            "description": "Optional customer identity document number stored with the reference."
          },
          "customMetadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Optional merchant-defined JSON object for internal reconciliation and record linking.\n\nThis is the direct PPR endpoint form: send `customMetadata` at the request root for `POST /api/references/ppr`, `/api/references/ppr/legacy`, and each item in `/api/references/ppr/bulk`. Do not wrap it in `metadata` or `custom`.\n\nProperty names are chosen by the merchant. Values may be strings, numbers, booleans, arrays, nested objects, or `null`. The values do not affect PPR processing and are returned unchanged as `customMetadata` in creation, detail, and list responses.\n\nDo not include credentials, card details, access tokens, or other secrets.",
            "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": "Payment creation response. The exact fields depend on the payment type and method.",
        "properties": {
          "id": {
            "type": "string",
            "description": "For compact PPR responses, this identifies the PPR reference record. Use `reference`, not this field, to call `GET /api/payments/{paymentId}`."
          },
          "internalId": {
            "type": "string",
            "format": "uuid",
            "description": "Internal payment identifier when included by the selected payment flow."
          },
          "entity": {
            "type": "string"
          },
          "reference": {
            "type": "string",
            "description": "Provider/payment reference. For PPR, use this value to retrieve payment details."
          },
          "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": "Transaction identifier."
          },
          "numLogSistema": {
            "type": "string",
            "description": "System log number associated with the payment notification."
          },
          "idLogSistema": {
            "type": "string",
            "description": "System period/log identifier."
          },
          "dataTransaccaoCliente": {
            "type": "string",
            "format": "date-time",
            "description": "Date and time when the customer payment was registered."
          },
          "montantePago": {
            "type": "number",
            "description": "Amount paid by the customer."
          },
          "tipoTerminal": {
            "type": "string",
            "description": "Terminal type used for the payment."
          },
          "iIdentTerminal": {
            "type": "string",
            "description": "Terminal identifier."
          },
          "localidadeTerminal": {
            "type": "string",
            "description": "Terminal location."
          },
          "refPagamento": {
            "type": "string",
            "description": "Payment reference paid by the customer."
          },
          "nib": {
            "type": "string",
            "nullable": true,
            "description": "Debit account NIB, when available."
          },
          "banco": {
            "type": "string",
            "nullable": true,
            "description": "Bank name, when available."
          },
          "Id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique notification identifier. Use this value for idempotency."
          }
        }
      },
      "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": "Date and time when the QR Code transaction was created."
          },
          "updatedDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date and time when the QR Code transaction status was updated."
          },
          "id": {
            "type": "string",
            "description": "Unique provider transaction identifier. Use this value for idempotency."
          },
          "amount": {
            "type": "number",
            "description": "Amount paid by the customer."
          },
          "clearingPeriod": {
            "type": "string",
            "description": "Clearing period associated with the transaction."
          },
          "transactionNumber": {
            "type": "string",
            "description": "Provider transaction number."
          },
          "status": {
            "type": "string",
            "description": "QR Code payment status.",
            "example": "ACCEPTED"
          },
          "transactionType": {
            "type": "string",
            "description": "Transaction type.",
            "example": "PAYMENT"
          },
          "orderOrigin": {
            "type": "string",
            "description": "Payment order origin.",
            "example": "QR_CODE"
          },
          "currency": {
            "type": "string",
            "description": "Payment currency.",
            "example": "AOA"
          },
          "reference": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "QR Code reference identifier."
              }
            }
          },
          "pointOfSale": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Point of sale identifier."
              }
            }
          },
          "merchantReferenceNumber": {
            "type": "string",
            "description": "Merchant reference number associated with the QR Code payment."
          }
        }
      },
      "MerchantWebhookResponse": {
        "type": "object",
        "required": [
          "Success",
          "Obs",
          "Id"
        ],
        "properties": {
          "Success": {
            "type": "boolean",
            "description": "Return true when the notification was processed successfully or was already processed before."
          },
          "Obs": {
            "type": "string",
            "description": "Short processing note."
          },
          "Id": {
            "type": "string",
            "description": "Merchant internal payment identifier."
          }
        }
      },
      "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"
            }
          }
        }
      }
    }
  }
}