{"openapi":"3.0.0","paths":{"/admin/audit-logs":{"get":{"description":"Newest first. Filter by actor email, exact action, and a created-at range.","operationId":"AuditController_list","parameters":[{"name":"actor","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"action","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"One page of entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAuditLogPage"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Audit log, filterable","tags":["Admin — audit"]}},"/admin/audit-logs/export":{"get":{"description":"Same filters as `GET /admin/audit-logs`; `page` and `pageSize` are accepted and ignored. Streamed newest first. The export is itself audited as `data.exported`, and that entry is not part of the file it describes.","operationId":"AuditController_export","parameters":[{"name":"actor","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"action","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"One row per entry, with `metadata` as JSON text.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Audit log as CSV","tags":["Admin — audit"]}},"/admin/accounts":{"get":{"operationId":"AccountsAdminController_list","parameters":[{"name":"search","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]}},{"name":"belowMinLiveBalance","required":false,"in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"One page of accounts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Accounts registry","tags":["Admin — accounts"]}},"/admin/accounts/export":{"get":{"description":"Same filters as `GET /admin/accounts`; `page` and `pageSize` are accepted and ignored. Streamed newest first. Audited as `data.exported`.","operationId":"AccountsAdminController_export","parameters":[{"name":"search","required":false,"in":"query","schema":{"type":"string","maxLength":200}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]}},{"name":"belowMinLiveBalance","required":false,"in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"One row per account: IDs, status, owner, wallet balance, MTD spend, created.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Accounts registry as CSV","tags":["Admin — accounts"]}},"/admin/accounts/{id}":{"get":{"operationId":"AccountsAdminController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The account detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such account."}},"security":[{"session":[]}],"summary":"One account, with wallet, KYC history, keys and recent activity","tags":["Admin — accounts"]}},"/admin/accounts/{id}/suspend":{"post":{"description":"ACTIVE → SUSPENDED. Audited with the mandatory reason.","operationId":"AccountsAdminController_suspend","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountStatusChange"}}}},"responses":{"200":{"description":"The updated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such account."},"409":{"description":"The account is not in a state that can be suspended."}},"security":[{"session":[]}],"summary":"Suspend an account","tags":["Admin — accounts"]}},"/admin/accounts/{id}/reactivate":{"post":{"description":"SUSPENDED → ACTIVE (if it was verified) or PENDING_KYC (if not). Audited.","operationId":"AccountsAdminController_reactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountStatusChange"}}}},"responses":{"200":{"description":"The updated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAccountDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such account."},"409":{"description":"The account is not suspended."}},"security":[{"session":[]}],"summary":"Reactivate a suspended account","tags":["Admin — accounts"]}},"/admin/settings":{"get":{"description":"Every setting with the value in force, where it comes from (stored, environment, or built-in default), what clearing the stored value would fall back to, and who last changed it.","operationId":"PlatformSettingsController_list","parameters":[],"responses":{"200":{"description":"The settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlatformSettings"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Platform settings","tags":["Admin — platform settings"]},"patch":{"description":"Stores an override (takes precedence over the environment variable of the same name) or, with `clear: true`, removes it so the environment variable — then the built-in default — applies again. `reason` is mandatory and recorded on the audit entry with the old and new values.","operationId":"PlatformSettingsController_update","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlatformSettingUpdate"}}}},"responses":{"200":{"description":"The updated settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlatformSettings"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Change or clear one setting","tags":["Admin — platform settings"]}},"/auth/signup":{"post":{"description":"Creates the account, its owner user and its wallet, and returns a session. The new account starts at PENDING_KYC.","operationId":"AuthController_signup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"201":{"description":"Account created; the caller is signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}}},"409":{"description":"That email address already has an account."}},"summary":"Create an account","tags":["Auth"]}},"/auth/login":{"post":{"operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"One of: a session (`SESSION`), a 2FA challenge (`TWO_FACTOR_REQUIRED`), or a forced-enrollment token (`TWO_FACTOR_SETUP_REQUIRED`). A super admin never receives a session here unless 2FA is not enabled — which it always is once enrolled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"401":{"description":"Wrong email or password. The two are not distinguished."},"429":{"description":"Too many sign-in attempts. Wait and try again."}},"summary":"Sign in","tags":["Auth"]}},"/auth/password-reset":{"post":{"description":"Emails a one-time reset link if the address belongs to an account. Answers 202 either way — the response does not reveal whether the address is registered.","operationId":"AuthController_requestPasswordReset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}}},"responses":{"202":{"description":"Accepted. A link has been sent if, and only if, the address has an account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetAcknowledgement"}}}}},"summary":"Request a password reset link","tags":["Auth"]}},"/auth/password-reset/confirm":{"post":{"description":"One-time: the token is spent on success, and the account’s other outstanding reset tokens are invalidated with it.","operationId":"AuthController_confirmPasswordReset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}}},"responses":{"200":{"description":"The password has been changed. Sign in with it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetAcknowledgement"}}}},"400":{"description":"The reset link is unknown, expired or has already been used."}},"summary":"Set a new password using a reset link","tags":["Auth"]}},"/auth/me":{"get":{"description":"Re-read from the database on every call, so `accountStatus` reflects a KYC approval or suspension that happened after the token was issued.","operationId":"AuthController_me","parameters":[],"responses":{"200":{"description":"The authenticated user and their account status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticatedUser"}}}}},"security":[{"session":[]}],"summary":"The current principal","tags":["Auth"]}},"/auth/2fa/status":{"get":{"operationId":"TwoFactorController_status","parameters":[],"responses":{"200":{"description":"Whether 2FA is enabled and how many recovery codes remain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorStatus"}}}}},"security":[{"session":[]}],"summary":"Two-factor status for the signed-in super admin","tags":["Auth — Two-factor"]}},"/auth/2fa/setup":{"post":{"description":"Generates a TOTP secret and an otpauth:// URI for the authenticator app. The response is the only time the secret is returned. 2FA is not enabled until the code is verified.","operationId":"TwoFactorController_setup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorSetupRequest"}}}},"responses":{"200":{"description":"Scan the QR code, then POST the code to /auth/2fa/setup/verify.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorSetup"}}}},"401":{"description":"The setup token is unknown, expired or already consumed."}},"summary":"Begin 2FA enrollment","tags":["Auth — Two-factor"]}},"/auth/2fa/setup/verify":{"post":{"description":"Enables 2FA, returns the recovery codes (shown once), and signs the admin in. Enabling does not happen until this succeeds.","operationId":"TwoFactorController_setupVerify","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorSetupVerify"}}}},"responses":{"200":{"description":"2FA enabled. Store the recovery codes — they cannot be retrieved again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorEnrollment"}}}},"401":{"description":"The code was not correct, or the setup expired."}},"summary":"Verify the first code and enable 2FA","tags":["Auth — Two-factor"]}},"/auth/2fa/verify":{"post":{"description":"Accepts a 6-digit TOTP code or one recovery code. Destroys the challenge; too many failures require signing in again.","operationId":"TwoFactorController_verify","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorVerify"}}}},"responses":{"200":{"description":"Signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}}},"401":{"description":"The code was wrong, or the challenge expired or was already used."},"429":{"description":"Too many incorrect attempts."}},"summary":"Complete a 2FA login","tags":["Auth — Two-factor"]}},"/auth/2fa/disable":{"post":{"operationId":"TwoFactorController_disable","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorSensitiveAction"}}}},"responses":{"200":{"description":"2FA disabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorStatus"}}}},"401":{"description":"The password or second factor was not correct."}},"security":[{"session":[]}],"summary":"Disable two-factor authentication","tags":["Auth — Two-factor"]}},"/auth/2fa/recovery-codes/regenerate":{"post":{"description":"Shown once. Your previous recovery codes stop working immediately.","operationId":"TwoFactorController_regenerate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorSensitiveAction"}}}},"responses":{"200":{"description":"The new recovery codes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwoFactorRecoveryCodes"}}}},"401":{"description":"The password or second factor was not correct."}},"security":[{"session":[]}],"summary":"Generate a new set of recovery codes","tags":["Auth — Two-factor"]}},"/admin/providers":{"get":{"description":"Every configurable field with a masked preview, where its value currently comes from (stored, environment, or unset), and who last changed it. Secrets are never returned in plaintext by this or any other endpoint.","operationId":"ProvidersController_list","parameters":[],"responses":{"200":{"description":"The configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderConfigList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Provider configuration, masked","tags":["Admin — providers"]}},"/admin/providers/{provider}/{key}":{"put":{"description":"Encrypted at rest and audited with the mandatory reason. A stored value takes precedence over the deployment environment variable of the same name.","operationId":"ProvidersController_put","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}},{"name":"key","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderCredentialUpdate"}}}},"responses":{"200":{"description":"The updated configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderConfigList"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such provider field."}},"security":[{"session":[]}],"summary":"Store or rotate one credential","tags":["Admin — providers"]},"delete":{"description":"Removes the stored value so the deployment environment variable takes over again. Audited. Does not unset the integration.","operationId":"ProvidersController_clear","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}},{"name":"key","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderCredentialDelete"}}}},"responses":{"200":{"description":"The updated configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderConfigList"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such provider field."}},"security":[{"session":[]}],"summary":"Clear a stored credential","tags":["Admin — providers"]}},"/kyc/uploads":{"post":{"description":"Documents go straight from the browser to MinIO under the returned policy (decisions.md D12) — no identity document passes through this API.","operationId":"KycController_createUploadTarget","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycUploadTargetRequest"}}}},"responses":{"200":{"description":"A short-lived presigned POST policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycUploadTarget"}}}}},"security":[{"session":[]}],"summary":"Get a presigned upload target","tags":["KYC"]}},"/kyc":{"post":{"operationId":"KycController_submit","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionRequest"}}}},"responses":{"201":{"description":"Submitted; the account stays PENDING_KYC until an admin reviews it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionSummary"}}}},"409":{"description":"A submission is already pending review."}},"security":[{"session":[]}],"summary":"Submit uploaded documents for review","tags":["KYC"]},"get":{"operationId":"KycController_list","parameters":[],"responses":{"200":{"description":"Every submission this account has made.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionSummaryList"}}}}},"security":[{"session":[]}],"summary":"Submission history, including rejection reasons","tags":["KYC"]}},"/admin/kyc/submissions":{"get":{"operationId":"KycAdminController_listPending","parameters":[],"responses":{"200":{"description":"Submissions awaiting review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionSummaryList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"The review queue, oldest first","tags":["Admin — KYC"]}},"/admin/kyc/submissions/{id}":{"get":{"description":"The links are short-lived — they should not outlive the review.","operationId":"KycAdminController_getForReview","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The submission and its documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionForReview"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such submission."}},"security":[{"session":[]}],"summary":"One submission, with presigned document links","tags":["Admin — KYC"]}},"/admin/kyc/submissions/{id}/approve":{"post":{"description":"Moves the account to ACTIVE. Audited against the reviewing admin.","operationId":"KycAdminController_approve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycApprovalRequest"}}}},"responses":{"201":{"description":"The reviewed submission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Approve","tags":["Admin — KYC"]}},"/admin/kyc/submissions/{id}/reject":{"post":{"description":"The reason is mandatory and is shown to the client.","operationId":"KycAdminController_reject","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycRejectionRequest"}}}},"responses":{"201":{"description":"The reviewed submission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KycSubmissionSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Reject","tags":["Admin — KYC"]}},"/wallet":{"get":{"operationId":"WalletController_get","parameters":[],"responses":{"200":{"description":"The account’s wallet, in MWK decimal strings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletSummary"}}}}},"security":[{"session":[]}],"summary":"Balance and reserved credit","tags":["Wallet"]}},"/wallet/live-eligibility":{"get":{"description":"The same check `POST /api-keys` applies (decisions.md D4, D5), exposed so the dashboard can explain a disabled button instead of failing the click.","operationId":"WalletController_getLiveEligibility","parameters":[],"responses":{"200":{"description":"Eligibility, with the reason when it is not met.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveKeyEligibility"}}}}},"security":[{"session":[]}],"summary":"Whether a live API key may be issued","tags":["Wallet"]}},"/wallet/transactions":{"get":{"description":"Keyset-paginated. Auto-refunds appear as their own REFUND line.","operationId":"WalletController_listTransactions","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["TOPUP","DEBIT","REFUND","ADJUSTMENT"]}}],"responses":{"200":{"description":"A page of ledger entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletTransactionPage"}}}}},"security":[{"session":[]}],"summary":"Ledger, newest first","tags":["Wallet"]}},"/admin/accounts/{accountId}/wallet":{"get":{"operationId":"WalletAdminController_get","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The wallet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Any account’s wallet","tags":["Admin — wallets"]}},"/admin/accounts/{accountId}/wallet/min-live-balance":{"patch":{"description":"Per-account override of the platform default (decisions.md D5). Audited.","operationId":"WalletAdminController_setMinLiveBalance","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinLiveBalanceUpdate"}}}},"responses":{"200":{"description":"The updated wallet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Override this account’s live-send threshold","tags":["Admin — wallets"]}},"/admin/accounts/{accountId}/wallet/adjust":{"post":{"description":"Signed amount; the mandatory note is recorded in the audit log.","operationId":"WalletAdminController_adjust","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletAdjustRequest"}}}},"responses":{"200":{"description":"The updated wallet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Manually adjust an account’s wallet balance","tags":["Admin — wallets"]}},"/wallet/topup":{"post":{"description":"Prompts the given handset to approve a mobile-money collection through InfiPay (decisions.md D13). Returns immediately with a reference and a PENDING status — poll `GET /wallet/topup/{reference}` until it resolves. The balance moves when InfiPay confirms the collection, not here.","operationId":"PaymentsController_initiateTopup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupRequest"}}}},"responses":{"200":{"description":"The collection has been pushed to the payer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupInitiation"}}}},"502":{"description":"InfiPay could not be reached or rejected the request."},"503":{"description":"InfiPay is not configured on this deployment."}},"security":[{"session":[]}],"summary":"Start a wallet top-up","tags":["Payments"]}},"/wallet/topup/{reference}":{"get":{"description":"Fetches the attempt from InfiPay and credits the wallet if the collection completed. Idempotent — polling this endpoint is the intended way to follow a top-up.","operationId":"PaymentsController_checkTopupStatus","parameters":[{"name":"reference","required":true,"in":"path","description":"The reference returned by POST /wallet/topup.","schema":{"type":"string"}}],"responses":{"200":{"description":"The attempt’s current state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusResult"}}}},"403":{"description":"That top-up belongs to another account."},"404":{"description":"Unknown top-up reference."}},"security":[{"session":[]}],"summary":"Check a wallet top-up","tags":["Payments"]}},"/admin/pricing-rules":{"get":{"description":"Rates are versioned by append (decisions.md D3): superseded rules stay, with a status saying so.","operationId":"PricingAdminController_list","parameters":[{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"country","required":false,"in":"query","schema":{"type":"string","pattern":"^[A-Z]{2}$"}},{"name":"network","required":false,"in":"query","schema":{"type":"string","maxLength":40,"pattern":"^[A-Z0-9]+(?:_[A-Z0-9]+)*$"}},{"name":"includeSuperseded","required":false,"in":"query","schema":{"default":"false","type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Matching rules.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingRuleList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Pricing rules","tags":["Admin — pricing"]},"post":{"description":"There is no PATCH: repricing means posting a new rule and leaving the old row in place.","operationId":"PricingAdminController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingRuleCreate"}}}},"responses":{"201":{"description":"The new rule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingRuleSummary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Create a rule — and the way a route is repriced","tags":["Admin — pricing"]}},"/admin/pricing-rules/coverage":{"get":{"description":"An unpriced route is rejected at send time rather than guessed at (D3), so this is the list of sends that would currently fail.","operationId":"PricingAdminController_coverage","parameters":[],"responses":{"200":{"description":"Coverage per channel.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingCoverageList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Which routes are priced, and what is exposed","tags":["Admin — pricing"]}},"/admin/pricing-rules/resolve":{"get":{"description":"Runs the same resolver the send pipeline uses — a re-implementation for the UI would answer a different question.","operationId":"PricingAdminController_resolve","parameters":[{"name":"channel","required":true,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"country","required":false,"in":"query","schema":{"default":null,"nullable":true,"type":"string","pattern":"^[A-Z]{2}$"}},{"name":"network","required":false,"in":"query","schema":{"default":null,"nullable":true,"type":"string","maxLength":40,"pattern":"^[A-Z0-9]+(?:_[A-Z0-9]+)*$"}},{"name":"at","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}}],"responses":{"200":{"description":"Priced, or explicitly unpriced.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceResolution"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"What a route would cost","tags":["Admin — pricing"]}},"/admin/pricing-rules/{id}":{"delete":{"description":"The only removal there is. Refused once the rule has taken effect.","operationId":"PricingAdminController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"Cancelled."},"403":{"description":"SUPER_ADMIN only."},"409":{"description":"The rule is already in effect and is now history."}},"security":[{"session":[]}],"summary":"Cancel a scheduled rate change","tags":["Admin — pricing"]}},"/pricing":{"get":{"description":"Local SMS per network, the international SMS default and email per recipient, each resolved the way a send would be. Null means the route is not priced and a send to it is rejected.","operationId":"PricingPublicController_rateCard","parameters":[],"responses":{"200":{"description":"Current rates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRateCard"}}}}},"summary":"Current rates","tags":["Pricing"]}},"/api-keys":{"get":{"operationId":"ApiKeysController_list","parameters":[{"name":"environment","required":false,"in":"query","schema":{"type":"string","enum":["SANDBOX","LIVE"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["ACTIVE","REVOKED"]}}],"responses":{"200":{"description":"Keys, without secrets — those are unrecoverable by design.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyList"}}}}},"security":[{"session":[]}],"summary":"This account’s keys","tags":["API keys"]},"post":{"description":"The only response in this API containing a key secret. It is stored as a peppered hash, so a client who loses it rotates rather than re-reads.","operationId":"ApiKeysController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}}},"responses":{"201":{"description":"The new key, with its secret shown once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyWithSecret"}}}},"403":{"description":"A LIVE key was requested before KYC approval and the minimum balance (D4, D5)."}},"security":[{"session":[]}],"summary":"Issue a key","tags":["API keys"]}},"/api-keys/{id}/rotate":{"post":{"description":"The old secret stops authenticating the instant the new one is issued — rotation is the response to a disclosed key, so there is no overlap window. To cut over gradually instead, create a second key, deploy it, then revoke the first.","operationId":"ApiKeysController_rotate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotate"}}}},"responses":{"201":{"description":"The new key (with secret) and the one it replaces.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotation"}}}},"404":{"description":"No such key on this account."}},"security":[{"session":[]}],"summary":"Mint a replacement and revoke the original","tags":["API keys"]}},"/api-keys/{id}/revoke":{"post":{"description":"Immediate and irreversible. The row remains so past messages stay attributable.","operationId":"ApiKeysController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"404":{"description":"No such key on this account."}},"security":[{"session":[]}],"summary":"Revoke a key","tags":["API keys"]}},"/admin/accounts/{accountId}/api-keys":{"get":{"description":"Newest first, revoked keys included, system keys excluded. Prefix only — secrets are stored as a peppered hash and never returned.","operationId":"ApiKeysAdminController_list","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The keys.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyList"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such account."}},"security":[{"session":[]}],"summary":"An account’s API keys","tags":["Admin — API keys"]}},"/admin/accounts/{accountId}/api-keys/{id}/revoke":{"post":{"description":"Immediate: the next request with the key is refused. Irreversible. The reason is mandatory, audited, and shown to the client on their keys screen.","operationId":"ApiKeysAdminController_revoke","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminApiKeyRevoke"}}}},"responses":{"200":{"description":"The revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such account, or no such key on it."},"409":{"description":"Already revoked."}},"security":[{"session":[]}],"summary":"Revoke a client’s API key","tags":["Admin — API keys"]}},"/v1/me":{"get":{"description":"What key am I holding and what may it do? Costs nothing and consumes no message — the first call a copy-paste snippet makes.","operationId":"V1IdentityController_me","parameters":[],"responses":{"200":{"description":"The key’s account, environment and scopes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyIdentity"}}}},"401":{"description":"Missing, unknown or revoked key."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Verify a key","tags":["Send API (v1)"]}},"/templates":{"get":{"operationId":"TemplatesController_list","parameters":[{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}}],"responses":{"200":{"description":"Templates, by name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}}},"security":[{"session":[]}],"summary":"This account’s templates","tags":["Templates"]},"post":{"description":"`variables` in the response is extracted from the stored body and subject, not echoed — it tells the client exactly which names their next send must supply.","operationId":"TemplatesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateCreate"}}}},"responses":{"201":{"description":"The created template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"400":{"description":"Placeholder syntax outside the supported subset, or a subject on an SMS template."},"409":{"description":"This account already has a template with that name."}},"security":[{"session":[]}],"summary":"Create a template","tags":["Templates"]}},"/templates/{templateId}":{"get":{"operationId":"TemplatesController_get","parameters":[{"name":"templateId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"404":{"description":"No such template on this account."}},"security":[{"session":[]}],"summary":"One template","tags":["Templates"]},"patch":{"description":"Messages already sent or scheduled keep their own rendered text — editing here cannot change what they say.","operationId":"TemplatesController_update","parameters":[{"name":"templateId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateUpdate"}}}},"responses":{"200":{"description":"The updated template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"404":{"description":"No such template on this account."}},"security":[{"session":[]}],"summary":"Edit a template","tags":["Templates"]},"delete":{"description":"Messages that used it keep their text and lose only the pointer.","operationId":"TemplatesController_remove","parameters":[{"name":"templateId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The deleted template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"404":{"description":"No such template on this account."}},"security":[{"session":[]}],"summary":"Delete a template","tags":["Templates"]}},"/admin/accounts/{accountId}/suppressions":{"get":{"description":"Newest first. Destinations are stored normalised (E.164 for SMS, lower-cased for email) and the `destination` filter is normalised the same way before matching.","operationId":"SuppressionsAdminController_list","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"reason","required":false,"in":"query","schema":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]}},{"name":"destination","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":320}}],"responses":{"200":{"description":"One page of suppressions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"One account's opt-out list","tags":["Admin — suppressions"]},"post":{"operationId":"SuppressionsAdminController_add","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionCreate"}}}},"responses":{"201":{"description":"The new suppression.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Suppression"}}}},"403":{"description":"SUPER_ADMIN only."},"409":{"description":"This destination is already suppressed for this account."}},"security":[{"session":[]}],"summary":"Suppress a destination for this account","tags":["Admin — suppressions"]}},"/admin/accounts/{accountId}/suppressions/{id}":{"delete":{"description":"Resumes messaging a destination that had opted out. Audited with the full deleted row, since nothing else will record that it existed.","operationId":"SuppressionsAdminController_remove","parameters":[{"name":"accountId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such suppression on this account."}},"security":[{"session":[]}],"summary":"Lift a suppression","tags":["Admin — suppressions"]}},"/v1/sender-domains":{"post":{"description":"Generates a 2048-bit DKIM key pair and a verification token for the domain and returns the DNS records to publish: an ownership TXT, the DKIM key, a bounce CNAME, and an SPF include: line to merge into your existing SPF record. Nothing is sent as the domain until POST /v1/sender-domains/{id}/verify sees the ownership and DKIM records.","operationId":"SenderDomainsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainCreate"}}}},"responses":{"201":{"description":"Added, pending verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"400":{"description":"Not a bare domain, or one of InfiSend’s own."},"401":{"description":"Missing, unknown or revoked API key."},"403":{"description":"The key lacks the EMAIL scope."},"409":{"description":"Already added, or too many unverified domains."},"429":{"description":"Rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Add a sending domain","tags":["Sender domains (v1)"]},"get":{"description":"Every domain on this account, with its status and records.","operationId":"SenderDomainsController_list","parameters":[],"responses":{"200":{"description":"This account’s domains.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainList"}}}},"401":{"description":"Missing, unknown or revoked API key."},"403":{"description":"The key lacks the EMAIL scope."},"429":{"description":"Rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"List sending domains","tags":["Sender domains (v1)"]}},"/v1/sender-domains/{id}":{"get":{"description":"Its status, the records to publish, and what the last check saw.","operationId":"SenderDomainsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"401":{"description":"Missing, unknown or revoked API key."},"403":{"description":"The key lacks the EMAIL scope."},"404":{"description":"No such domain on this account."},"429":{"description":"Rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"One sending domain","tags":["Sender domains (v1)"]},"delete":{"description":"Immediately blocks further sends from the domain. With queued or scheduled messages still under it, answers 409 with their count unless force=true; those messages are then failed and refunded instead of sent.","operationId":"SenderDomainsController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"force","required":false,"in":"query","description":"Revoke even with messages still queued under the domain.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainRevoked"}}}},"401":{"description":"Missing, unknown or revoked API key."},"403":{"description":"The key lacks the EMAIL scope."},"404":{"description":"No such domain on this account."},"409":{"description":"Messages are still queued under the domain; repeat with force=true."},"429":{"description":"Rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Revoke a sending domain","tags":["Sender domains (v1)"]}},"/v1/sender-domains/{id}/verify":{"post":{"description":"VERIFIED only when both the ownership TXT and the DKIM key resolve and match. Either one missing or different is FAILED, with the record named; a DNS lookup that times out changes nothing. Also how a FAILED domain is restored.","operationId":"SenderDomainsController_verify","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain after the check.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"401":{"description":"Missing, unknown or revoked API key."},"403":{"description":"The key lacks the EMAIL scope."},"404":{"description":"No such domain on this account."},"429":{"description":"Rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Check a sending domain’s DNS records","tags":["Sender domains (v1)"]}},"/sender-domains":{"post":{"description":"The dashboard twin of POST /v1/sender-domains: generates the DKIM key pair and verification token and returns the DNS records to publish.","operationId":"SenderDomainsDashboardController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainCreate"}}}},"responses":{"201":{"description":"Added, pending verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"400":{"description":"Not a bare domain, or one of InfiSend’s own."},"409":{"description":"Already added, or too many unverified domains."},"429":{"description":"Too many additions or verification attempts for this account."},"503":{"description":"Custom sending domains are not enabled on this deployment."}},"security":[{"session":[]}],"summary":"Add a sending domain","tags":["Sender domains"]},"get":{"description":"Every domain on this account, with its status and records.","operationId":"SenderDomainsDashboardController_list","parameters":[],"responses":{"200":{"description":"This account’s domains.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainList"}}}}},"security":[{"session":[]}],"summary":"List sending domains","tags":["Sender domains"]}},"/sender-domains/{id}":{"get":{"description":"Its status, the records to publish, and what the last check saw.","operationId":"SenderDomainsDashboardController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"404":{"description":"No such domain on this account."}},"security":[{"session":[]}],"summary":"One sending domain","tags":["Sender domains"]},"delete":{"description":"Immediately blocks further sends from the domain. With queued or scheduled messages still under it, answers 409 with their count unless force=true; those messages are then failed and refunded instead of sent.","operationId":"SenderDomainsDashboardController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"force","required":false,"in":"query","description":"Revoke even with messages still queued under the domain.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomainRevoked"}}}},"404":{"description":"No such domain on this account."},"409":{"description":"Messages are still queued under the domain; repeat with force=true."}},"security":[{"session":[]}],"summary":"Revoke a sending domain","tags":["Sender domains"]}},"/sender-domains/{id}/verify":{"post":{"description":"VERIFIED only when both the ownership TXT and the DKIM key resolve and match. Either one missing or different is FAILED, with the record named; a DNS lookup that times out changes nothing.","operationId":"SenderDomainsDashboardController_verify","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain after the check.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SenderDomain"}}}},"404":{"description":"No such domain on this account."},"429":{"description":"Too many additions or verification attempts for this account."}},"security":[{"session":[]}],"summary":"Check a sending domain’s DNS records","tags":["Sender domains"]}},"/admin/sender-domains":{"get":{"description":"Worst reputation first: highest live-email bounce rate over the last 30 days, then worst verification status. Each row carries the last check’s outcome per DNS record and any suspension.","operationId":"SenderDomainsAdminController_list","parameters":[{"name":"accountId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]}},{"name":"suspended","required":false,"in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"One page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainList"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Sender domains across accounts","tags":["Admin — sender domains"]}},"/admin/sender-domains/{id}":{"get":{"description":"The records, the last check, the DNS check history and the queued mail under it.","operationId":"SenderDomainsAdminController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such domain."}},"security":[{"session":[]}],"summary":"One sender domain","tags":["Admin — sender domains"]}},"/admin/sender-domains/{id}/recheck":{"post":{"description":"On a VERIFIED domain, the periodic DKIM re-check, which can demote it. On a PENDING or FAILED one, the full verification, which can promote it. Recorded in the check history; does not affect a suspension.","operationId":"SenderDomainsAdminController_recheck","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The domain after the check.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such domain."}},"security":[{"session":[]}],"summary":"Re-check a sender domain’s DNS now","tags":["Admin — sender domains"]}},"/admin/sender-domains/{id}/suspend":{"post":{"description":"Nothing may be sent From the domain until it is unsuspended, whatever its verification status; queued mail under it is failed and refunded by the worker. The reason is mandatory, audited, and shown to the client.","operationId":"SenderDomainsAdminController_suspend","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainAction"}}}},"responses":{"200":{"description":"The suspended domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such domain."},"409":{"description":"Already suspended."}},"security":[{"session":[]}],"summary":"Suspend a sender domain","tags":["Admin — sender domains"]}},"/admin/sender-domains/{id}/unsuspend":{"post":{"description":"Sends resume if the domain is also VERIFIED. The reason is mandatory and audited.","operationId":"SenderDomainsAdminController_unsuspend","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainAction"}}}},"responses":{"200":{"description":"The domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSenderDomainDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such domain."},"409":{"description":"Not suspended."}},"security":[{"session":[]}],"summary":"Lift a sender domain suspension","tags":["Admin — sender domains"]}},"/v1/sms/send":{"post":{"description":"Asynchronous: returns once the row is written and the credit reserved. The outcome arrives on your webhook. Supply `templateId` + `variables`, or `message`, but not both. A `scheduledFor` in the future queues it for the sweep.","operationId":"SendController_sendSms","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, on every send endpoint including bulk. A repeat of the same key with the same request returns the original result (`duplicate: true`) instead of sending again; the same key with a different request is a 409 IdempotencyKeyConflict.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsSendRequest"}}}},"responses":{"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendAccepted"}}}},"400":{"description":"Unpriced route, invalid recipient, or template variables not satisfied."},"401":{"description":"Missing, unknown or revoked API key."},"402":{"description":"Insufficient wallet balance for this send."},"403":{"description":"The key lacks the scope this channel requires."},"409":{"description":"IdempotencyKeyConflict: the key was already used for a different request."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Send one SMS","tags":["Send API (v1)"]}},"/v1/email/send":{"post":{"description":"Always exactly **one** email (one message, one Message-ID). `to` is an address or an array of addresses; `cc` and `bcc` are optional arrays. Naming more than one `to` address requires `mode: \"SHARED\"` — every recipient then receives the same email and sees the To and Cc lines; Bcc recipients are on the SMTP envelope only and never appear in any header. To send each recipient a **separate** email, use `POST /v1/email/bulk`. Billing is per recipient: To + Cc + Bcc addresses × the email rate, reserved in full up front (402 if the wallet cannot cover every recipient). The per-email recipient limit is `EMAIL_MAX_RECIPIENTS_PER_MESSAGE` (413 above it). Any suppressed recipient refuses the whole email (403). An inline email needs `subject` and a body; a templated one needs neither. Reusing an idempotency key with a different request is a 409.","operationId":"SendController_sendEmail","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, on every send endpoint including bulk. A repeat of the same key with the same request returns the original result (`duplicate: true`) instead of sending again; the same key with a different request is a 409 IdempotencyKeyConflict.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendRequest"}}}},"responses":{"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendAccepted"}}}},"400":{"description":"Invalid or duplicate recipient, missing `mode: \"SHARED\"` for several `to` addresses, unpriced route, or template variables not satisfied."},"401":{"description":"Missing, unknown or revoked API key."},"402":{"description":"Insufficient wallet balance for this send."},"403":{"description":"A recipient is on the suppression list — nothing is sent to anyone."},"409":{"description":"IdempotencyKeyConflict: the key was already used for a different request."},"413":{"description":"More To + Cc + Bcc recipients than one shared email may carry."},"422":{"description":"`from` is on a domain that is not VERIFIED for this account (SenderDomainNotVerified), or is another address on InfiSend’s own domain."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Send one email — to one recipient, or shared by several","tags":["Send API (v1)"]}},"/v1/sms/bulk":{"post":{"description":"One `Message` row and one queue job per recipient (decisions.md D9), created in a single all-or-nothing transaction: a list the wallet cannot fully cover leaves zero rows behind. Recipients arrive as an array or as `recipientsCsv`. There is no built-in cap (D10).","operationId":"SendController_sendSmsBulk","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, on every send endpoint including bulk. A repeat of the same key with the same request returns the original result (`duplicate: true`) instead of sending again; the same key with a different request is a 409 IdempotencyKeyConflict.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsBulkSendRequest"}}}},"responses":{"202":{"description":"The whole batch was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendAccepted"}}}},"400":{"description":"Any unusable recipient row rejects the whole batch — see POST /messages/bulk-preview."},"401":{"description":"Missing, unknown or revoked API key."},"402":{"description":"Insufficient wallet balance for this send."},"403":{"description":"The key lacks the scope this channel requires."},"409":{"description":"IdempotencyKeyConflict: the key was already used for a different request."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Send SMS to many recipients","tags":["Send API (v1)"]}},"/v1/email/bulk":{"post":{"description":"The individual-send pipeline: **one email per recipient**, each its own `Message` with its own id, status, retries, webhooks and charge (decisions.md D9) — recipients never see one another. Per-recipient `variables` make it a mail-merge. Created in a single all-or-nothing transaction: a list the wallet cannot fully cover leaves zero rows behind. Recipients arrive as an array or as `recipientsCsv`; a duplicate address in either is a 400. Every message shares the response’s `batchId`. Replay-safe with an idempotency key; the same key with a different request is a 409. There is no built-in cap (D10). To send **one** email to several people (To/Cc/Bcc), use `POST /v1/email/send`.","operationId":"SendController_sendEmailBulk","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, on every send endpoint including bulk. A repeat of the same key with the same request returns the original result (`duplicate: true`) instead of sending again; the same key with a different request is a 409 IdempotencyKeyConflict.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailBulkSendRequest"}}}},"responses":{"202":{"description":"The whole batch was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendAccepted"}}}},"400":{"description":"Any unusable or duplicate recipient row rejects the whole batch — see POST /messages/bulk-preview."},"401":{"description":"Missing, unknown or revoked API key."},"402":{"description":"Insufficient wallet balance for this send."},"403":{"description":"The key lacks the scope this channel requires."},"409":{"description":"IdempotencyKeyConflict: the key was already used for a different request."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Send each recipient a separate email","tags":["Send API (v1)"]}},"/v1/messages/{messageId}/cancel":{"post":{"description":"Refunds the reservation. Losing the race against the sweep is a 409, not a silent success.","operationId":"SendController_cancelScheduled","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, on every send endpoint including bulk. A repeat of the same key with the same request returns the original result (`duplicate: true`) instead of sending again; the same key with a different request is a 409 IdempotencyKeyConflict.","required":false,"schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The cancelled message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"401":{"description":"Missing, unknown or revoked API key."},"402":{"description":"Insufficient wallet balance for this send."},"403":{"description":"The key lacks the scope this channel requires."},"404":{"description":"No such message on this account."},"409":{"description":"Already released to the queue, or not scheduled at all."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Cancel a scheduled message","tags":["Send API (v1)"]}},"/send/limits":{"get":{"description":"`maxRecipients` is the platform bulk recipient cap (null when there is none); `maxRequestBodyBytes` is the largest JSON body the API accepts. Both are enforced on the send regardless.","operationId":"DashboardSendController_limits","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, exactly as on the /v1 send routes.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The current limits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendLimits"}}}},"402":{"description":"Insufficient wallet balance for this send."}},"security":[{"session":[]}],"summary":"The bounds on a dashboard bulk send","tags":["Send (dashboard)"]}},"/send/sms":{"post":{"description":"The same pipeline as the `/v1/*` send, entered with a session instead of an API key: same pricing, same wallet reservation, same idempotency, same webhooks. `environment` is in the body because a session, unlike a key, does not state one — and it defaults to SANDBOX. A LIVE request passes the same decisions.md D5 gate as a client-created live key.","operationId":"DashboardSendController_sendSms","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, exactly as on the /v1 send routes.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardSmsSendRequest"}}}},"responses":{"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendAccepted"}}}},"402":{"description":"Insufficient wallet balance for this send."}},"security":[{"session":[]}],"summary":"Send one SMS as the signed-in user","tags":["Send (dashboard)"]}},"/send/email":{"post":{"description":"The same pipeline as the `/v1/*` send, entered with a session instead of an API key: same pricing, same wallet reservation, same idempotency, same webhooks. `environment` is in the body because a session, unlike a key, does not state one — and it defaults to SANDBOX. A LIVE request passes the same decisions.md D5 gate as a client-created live key.","operationId":"DashboardSendController_sendEmail","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, exactly as on the /v1 send routes.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardEmailSendRequest"}}}},"responses":{"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendAccepted"}}}},"402":{"description":"Insufficient wallet balance for this send."}},"security":[{"session":[]}],"summary":"Send one email as the signed-in user","tags":["Send (dashboard)"]}},"/send/sms/bulk":{"post":{"description":"The same pipeline as the `/v1/*` send, entered with a session instead of an API key: same pricing, same wallet reservation, same idempotency, same webhooks. `environment` is in the body because a session, unlike a key, does not state one — and it defaults to SANDBOX. A LIVE request passes the same decisions.md D5 gate as a client-created live key.","operationId":"DashboardSendController_sendSmsBulk","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, exactly as on the /v1 send routes.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardSmsBulkSendRequest"}}}},"responses":{"202":{"description":"The whole batch was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendAccepted"}}}},"402":{"description":"Insufficient wallet balance for this send."}},"security":[{"session":[]}],"summary":"Bulk SMS as the signed-in user","tags":["Send (dashboard)"]}},"/send/email/bulk":{"post":{"description":"The same pipeline as the `/v1/*` send, entered with a session instead of an API key: same pricing, same wallet reservation, same idempotency, same webhooks. `environment` is in the body because a session, unlike a key, does not state one — and it defaults to SANDBOX. A LIVE request passes the same decisions.md D5 gate as a client-created live key.","operationId":"DashboardSendController_sendEmailBulk","parameters":[{"name":"idempotency-key","in":"header","description":"Replay protection, exactly as on the /v1 send routes.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardEmailBulkSendRequest"}}}},"responses":{"202":{"description":"The whole batch was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendAccepted"}}}},"402":{"description":"Insufficient wallet balance for this send."}},"security":[{"session":[]}],"summary":"Bulk email as the signed-in user","tags":["Send (dashboard)"]}},"/messages":{"get":{"description":"Keyset-paginated. Sandbox and live sends are both here, distinguished by `environment`.","operationId":"MessagesController_list","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"environment","required":false,"in":"query","schema":{"type":"string","enum":["SANDBOX","LIVE"]}},{"name":"since","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"until","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"search","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":320}},{"name":"batchId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"A page of messages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagePage"}}}}},"security":[{"session":[]}],"summary":"Message log, newest first","tags":["Messages"]}},"/messages/scheduled":{"get":{"description":"Unpaginated and capped at 200, soonest first. Already-released messages are ordinary history and appear in the main log.","operationId":"MessagesController_listScheduled","parameters":[],"responses":{"200":{"description":"Cancellable scheduled messages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledMessageList"}}}}},"security":[{"session":[]}],"summary":"Scheduled sends that have not fired","tags":["Messages"]}},"/messages/bulk-preview":{"post":{"description":"Creates nothing and reserves nothing. Bad rows and unpriced routes come back as data, not as a 400, because the caller is assembling a list.","operationId":"MessagesController_previewBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendPreviewRequest"}}}},"responses":{"200":{"description":"Total cost, per-route breakdown and any problem rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendPreview"}}}}},"security":[{"session":[]}],"summary":"Price a recipient list without sending","tags":["Messages"]}},"/messages/{messageId}":{"get":{"description":"For an email, `recipients` lists every To, Cc and Bcc address with its own status. Empty for SMS.","operationId":"MessagesController_get","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The message and its recipients.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWithRecipients"}}}},"404":{"description":"No such message on this account."}},"security":[{"session":[]}],"summary":"One message, with every recipient","tags":["Messages"]}},"/messages/{messageId}/events":{"get":{"description":"Oldest first. `timestamp` is when the event happened per whoever observed it; `createdAt` is when Infitech recorded it.","operationId":"MessagesController_listEvents","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The message's events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEventList"}}}},"404":{"description":"No such message on this account."}},"security":[{"session":[]}],"summary":"One message's event history","tags":["Messages"]}},"/messages/{messageId}/cancel":{"post":{"description":"Refunds the reservation. Losing the race against the sweep is a 409, not a silent success.","operationId":"MessagesController_cancelScheduled","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The cancelled message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"404":{"description":"No such message on this account."},"409":{"description":"Already released to the queue, or not scheduled at all."}},"security":[{"session":[]}],"summary":"Cancel a scheduled message","tags":["Messages"]}},"/v1/messages":{"get":{"description":"Only messages in the calling key’s own environment — a sandbox key lists sandbox messages, a live key live ones. Keyset-paginated with `cursor`/`limit`. Filter by `batchId` (every message one bulk request created), `status`, `channel`, a `since`/`until` window, or `search` (a recipient fragment — To, Cc or Bcc — or an exact message id). Each row carries `recipientCount`; `GET /v1/messages/:id` lists the recipients. For status changes, use your webhook rather than polling this.","operationId":"MessageEventsController_listMessages","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"environment","required":false,"in":"query","schema":{"type":"string","enum":["SANDBOX","LIVE"]}},{"name":"since","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"until","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"search","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":320}},{"name":"batchId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"A page of messages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagePage"}}}},"401":{"description":"Missing, unknown or revoked API key."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"List messages, newest first","tags":["Send API (v1)"]}},"/v1/messages/{messageId}":{"get":{"description":"Adds `recipients` — for an email, every To, Cc and Bcc address with its own status and failure detail (empty for SMS) — and `engagement`: `deliveredAt`, `firstOpenedAt`, `openCount` (unique, 0 or 1), `clickCount` and `clickedLinks`. Open and click figures are null for SMS, and for a shared email they are the message’s, not any one recipient’s. ⚠️ Opens include Apple Mail Privacy Protection pre-fetches and clicks can include security scanners — read them as upper bounds and engagement signals, not literal human actions; `engagement.caveats` says so in every response. For status changes, use your webhook rather than polling this.","operationId":"MessageEventsController_get","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The message and its engagement summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWithEngagement"}}}},"401":{"description":"Missing, unknown or revoked API key."},"404":{"description":"No such message on this account."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"One message, with its engagement summary","tags":["Send API (v1)"]}},"/v1/messages/{messageId}/events":{"get":{"description":"Oldest first. A delivered message has a `DELIVERED` event whose `timestamp` is the provider’s instant and whose `createdAt` is when Infitech recorded it — the two differ when a report is relayed slowly.","operationId":"MessageEventsController_list","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The message's events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEventList"}}}},"401":{"description":"Missing, unknown or revoked API key."},"404":{"description":"No such message on this account."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"One message's event history","tags":["Send API (v1)"]}},"/admin/messages":{"get":{"description":"Newest first, keyset-paginated like `GET /messages`. `recipient` is an exact match after normalisation (E.164 for SMS, lower-cased for email). `provider` is derived from the channel. Rows carry no subject or body — open a message for its content.","operationId":"AdminMessagesController_list","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"accountId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"messageId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"recipient","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":320}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]}},{"name":"provider","required":false,"in":"query","schema":{"type":"string","enum":["AFRICAS_TALKING","SMTP"]}},{"name":"environment","required":false,"in":"query","schema":{"type":"string","enum":["SANDBOX","LIVE"]}},{"name":"since","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"until","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}}],"responses":{"200":{"description":"A page of messages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMessagePage"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Every account’s messages, filterable","tags":["Admin — messages"]}},"/admin/messages/export":{"get":{"description":"Same filters as `GET /admin/messages`; `limit` and `cursor` are accepted and ignored. Streamed newest first. Metadata only: no subject or body. Audited as `data.exported` with the filters.","operationId":"AdminMessagesController_export","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"accountId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"messageId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"recipient","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":320}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]}},{"name":"provider","required":false,"in":"query","schema":{"type":"string","enum":["AFRICAS_TALKING","SMTP"]}},{"name":"environment","required":false,"in":"query","schema":{"type":"string","enum":["SANDBOX","LIVE"]}},{"name":"since","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"until","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}}],"responses":{"200":{"description":"One row per message: the list row’s fields.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Every account’s messages as CSV","tags":["Admin — messages"]}},"/admin/messages/{messageId}":{"get":{"description":"Returns the message content, so every call writes a `message.viewed` audit entry naming the admin. A 404 is not audited.","operationId":"AdminMessagesController_get","parameters":[{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The message and everything recorded about it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMessageDetail"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such message."}},"security":[{"session":[]}],"summary":"One message, with history, provider response, charges and webhooks","tags":["Admin — messages"]}},"/webhooks/endpoints":{"get":{"description":"Never includes signing secrets — those appear only at registration and rotation.","operationId":"WebhooksController_listEndpoints","parameters":[],"responses":{"200":{"description":"This account’s endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}}},"security":[{"session":[]}],"summary":"Registered endpoints","tags":["Webhooks"]},"post":{"description":"Returns the signing secret **once**. Verify deliveries with it per the `x-infitech-signature` scheme (HMAC-SHA-256 over `t.rawBody`). Omitting `events` subscribes to every event. https is required except on localhost.","operationId":"WebhooksController_createEndpoint","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}}},"responses":{"201":{"description":"The endpoint, with its signing secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointWithSecret"}}}},"409":{"description":"This account already has an endpoint on that URL."}},"security":[{"session":[]}],"summary":"Register an endpoint","tags":["Webhooks"]}},"/webhooks/endpoints/{endpointId}":{"get":{"operationId":"WebhooksController_getEndpoint","parameters":[{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"404":{"description":"No such endpoint on this account."}},"security":[{"session":[]}],"summary":"One endpoint","tags":["Webhooks"]},"patch":{"description":"Set `status` to DISABLED to stop delivery while keeping the attempt log.","operationId":"WebhooksController_updateEndpoint","parameters":[{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdate"}}}},"responses":{"200":{"description":"The updated endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"404":{"description":"No such endpoint on this account."},"409":{"description":"Another of this account’s endpoints already uses that URL."}},"security":[{"session":[]}],"summary":"Edit an endpoint","tags":["Webhooks"]},"delete":{"description":"Takes its attempt log with it. Disable instead if you want to keep the history.","operationId":"WebhooksController_removeEndpoint","parameters":[{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The deleted endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"404":{"description":"No such endpoint on this account."}},"security":[{"session":[]}],"summary":"Delete an endpoint","tags":["Webhooks"]}},"/webhooks/endpoints/{endpointId}/rotate-secret":{"post":{"description":"Immediate cutover — the previous secret stops verifying as soon as this returns. Deploy your handler’s new secret before calling it, not after.","operationId":"WebhooksController_rotateEndpointSecret","parameters":[{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The endpoint, with its new secret shown once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointWithSecret"}}}},"404":{"description":"No such endpoint on this account."}},"security":[{"session":[]}],"summary":"Mint a new signing secret","tags":["Webhooks"]}},"/webhooks/deliveries":{"get":{"description":"One row per attempt, not per event: a delivery that exhausted the five-attempt ladder (decisions.md D11) appears five times, the first four PENDING and the last FAILED.","operationId":"WebhooksController_listDeliveries","parameters":[{"name":"limit","required":false,"in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string","minLength":1}},{"name":"webhookEndpointId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"messageId","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["PENDING","DELIVERED","FAILED"]}}],"responses":{"200":{"description":"A page of attempts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryPage"}}}}},"security":[{"session":[]}],"summary":"Delivery attempts, newest first","tags":["Webhooks"]}},"/webhooks/deliveries/{deliveryId}":{"get":{"operationId":"WebhooksController_getDelivery","parameters":[{"name":"deliveryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The attempt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"404":{"description":"No such delivery on this account."}},"security":[{"session":[]}],"summary":"One attempt, with the payload sent and the response received","tags":["Webhooks"]}},"/webhooks/deliveries/{deliveryId}/resend":{"post":{"description":"Queues a fresh five-attempt ladder with the original payload byte-for-byte (same `occurredAt`) under a new signature timestamp. Works on a delivered attempt as readily as a failed one. The original rows are never modified; the replay appears as new ones.","operationId":"WebhooksController_resendDelivery","parameters":[{"name":"deliveryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"202":{"description":"The replay is queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResendAccepted"}}}},"404":{"description":"No such delivery on this account."},"409":{"description":"The endpoint is disabled; re-enable it before resending."},"422":{"description":"The stored payload predates a shape change and cannot be replayed."}},"security":[{"session":[]}],"summary":"Replay a logged delivery","tags":["Webhooks"]}},"/admin/revenue":{"get":{"description":"Top-ups, client charge and provider cost bucketed by day, week or month, plus the highest-revenue accounts in the window. Live traffic only. Compare `costedMessageCount` with `messageCount` before trusting the margin: the difference is traffic whose provider cost is unknown or not in MWK.","operationId":"RevenueController_report","parameters":[{"name":"granularity","required":false,"in":"query","schema":{"default":"MONTH","type":"string","enum":["DAY","WEEK","MONTH"]}},{"name":"periods","required":false,"in":"query","schema":{"default":6,"type":"integer","minimum":1,"maximum":24}},{"name":"accountLimit","required":false,"in":"query","schema":{"default":10,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"The report.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRevenueReport"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Revenue, provider cost and margin","tags":["Admin — revenue"]}},"/admin/revenue/export/periods":{"get":{"description":"The report’s buckets for the same `granularity` and `periods`, oldest first. Live traffic only. Audited as `data.exported`.","operationId":"RevenueController_exportPeriods","parameters":[{"name":"granularity","required":false,"in":"query","schema":{"default":"MONTH","type":"string","enum":["DAY","WEEK","MONTH"]}},{"name":"periods","required":false,"in":"query","schema":{"default":6,"type":"integer","minimum":1,"maximum":24}},{"name":"accountLimit","required":false,"in":"query","schema":{"default":10,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"One row per period: top-ups, client charge, provider cost, margin, message counts.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Revenue by period as CSV","tags":["Admin — revenue"]}},"/admin/revenue/export/accounts":{"get":{"description":"Every account with live traffic in the report’s window (not only the top `accountLimit`, which is ignored), in account ID order. Audited as `data.exported`.","operationId":"RevenueController_exportAccounts","parameters":[{"name":"granularity","required":false,"in":"query","schema":{"default":"MONTH","type":"string","enum":["DAY","WEEK","MONTH"]}},{"name":"periods","required":false,"in":"query","schema":{"default":6,"type":"integer","minimum":1,"maximum":24}},{"name":"accountLimit","required":false,"in":"query","schema":{"default":10,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"One row per account: client charge, provider cost, margin, message counts, and the window.","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Revenue by account as CSV","tags":["Admin — revenue"]}},"/v1/analytics/engagement":{"get":{"description":"Messages created in `[from, to)` on your account — default the last 30 days, at most 366, live traffic unless `environment=SANDBOX`. Rates are percentages to two places, null when their denominator is zero. ⚠️ `openRate` includes Apple Mail Privacy Protection pre-fetches and is an upper bound, not a count of human reads; `caveats` in every response lists what each figure does not mean.","operationId":"AnalyticsController_engagement","parameters":[{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"environment","required":false,"in":"query","schema":{"default":"LIVE","type":"string","enum":["SANDBOX","LIVE"]}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["SMS","EMAIL"]}}],"responses":{"200":{"description":"The report.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAnalytics"}}}},"400":{"description":"`from` not before `to`, or a window longer than 366 days."},"401":{"description":"Missing, unknown or revoked API key."},"429":{"description":"Per-key rate limit exceeded."}},"security":[{"apiKey":[]}],"summary":"Delivery, open and click rates over a window","tags":["Analytics (v1)"]}},"/admin/system/health":{"get":{"description":"Postgres and Redis connectivity, per-queue job counts and oldest waiting job age, worker liveness from Redis heartbeats, and each provider circuit breaker as the workers report it.","operationId":"SystemHealthController_check","parameters":[],"responses":{"200":{"description":"The snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSystemHealth"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"System health","tags":["Admin — system health"]}},"/admin/system/queues/{name}/failed":{"get":{"description":"Most recently failed first, with the failure reason and linked message.","operationId":"SystemHealthController_listFailed","parameters":[{"name":"page","required":false,"in":"query","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"pageSize","required":false,"in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"name","required":true,"in":"path","description":"The BullMQ queue.","schema":{"enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"],"type":"string"}}],"responses":{"200":{"description":"One page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminFailedJobPage"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Failed jobs in one queue","tags":["Admin — system health"]}},"/admin/system/queues/{name}/failed/{jobId}/retry":{"post":{"description":"Moves the job back to waiting with its attempt count reset. On a send queue, refused with 409 unless the message is still QUEUED and — on a live key — its credit reservation is still held, so a retry can never send without a charge or charge twice. `reason` is mandatory and audited.","operationId":"SystemHealthController_retry","parameters":[{"name":"jobId","required":true,"in":"path","schema":{}},{"name":"name","required":true,"in":"path","description":"The BullMQ queue.","schema":{"enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminFailedJobAction"}}}},"responses":{"200":{"description":"Retried.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminFailedJobActionResult"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such job in that queue."},"409":{"description":"The job is no longer failed, or retrying it would be unsafe; the message says which."}},"security":[{"session":[]}],"summary":"Retry a failed job","tags":["Admin — system health"]}},"/admin/system/queues/{name}/failed/{jobId}/discard":{"post":{"description":"Removes the job. On a send queue whose message is still QUEUED, the message is first failed and its reservation refunded (the client is notified as for any failed send), so no credit is stranded. `reason` is mandatory and audited.","operationId":"SystemHealthController_discard","parameters":[{"name":"jobId","required":true,"in":"path","schema":{}},{"name":"name","required":true,"in":"path","description":"The BullMQ queue.","schema":{"enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminFailedJobAction"}}}},"responses":{"200":{"description":"Discarded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminFailedJobActionResult"}}}},"403":{"description":"SUPER_ADMIN only."},"404":{"description":"No such job in that queue."},"409":{"description":"The job is no longer failed."}},"security":[{"session":[]}],"summary":"Discard a failed job","tags":["Admin — system health"]}},"/admin/overview":{"get":{"description":"Live message volume today and over the last 7 UTC days, with delivery rate; pending KYC; active accounts below their live-send threshold; failed jobs and unhealthy circuit breakers; revenue this month against last; recent suspensions and audit entries. Each figure is computed by the same code as the screen it summarises.","operationId":"OverviewController_get","parameters":[],"responses":{"200":{"description":"The overview.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOverview"}}}},"403":{"description":"SUPER_ADMIN only."}},"security":[{"session":[]}],"summary":"Console overview","tags":["Admin — overview"]}},"/health":{"get":{"description":"No authentication. Does not touch Postgres or Redis.","operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"The process is up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"summary":"Liveness probe","tags":["Health"]}}},"info":{"title":"InfiSend","description":"InfiSend — SMS via Africa's Talking and email via SMTP behind one API,\nbilled per message from a prepaid MWK wallet.\n\n## Authentication\n\nTwo schemes, and which one an endpoint takes is part of its contract:\n\n- **session** — a dashboard JWT, `Authorization: Bearer <token>` from\n  `POST /auth/login`. Used by everything that *administers* an account: wallet,\n  API keys, templates, KYC, webhooks, message logs.\n- **apiKey** — an API key, `Authorization: Bearer sk_live_…` or `sk_test_…`.\n  Used by the `/v1/*` machine surface, which is send-only. Keys are scoped\n  (SMS / EMAIL / READ_ONLY) and rate-limited per key.\n\nA key cannot manage the account and a session cannot be handed to a server-side\nintegration: a leaked send credential must not be able to mint itself a live key or\nrepoint a webhook.\n\n## Environments\n\nEvery key is either `SANDBOX` or `LIVE`. Sandbox mirrors live behaviour exactly —\nsame status transitions, same webhook payloads, simulated delays and failures — and\nnever charges the wallet or reaches a provider.\n\n## Money\n\nAmounts are decimal **strings** in MWK, never JSON numbers. A float in a wallet balance\nis not recoverable after the fact, so the wire format refuses to carry one.\n\n## Sending is asynchronous\n\nA send returns `202` with a `messageId` once the message is written and the wallet\ncredit reserved. The outcome arrives on your registered webhook\n(`POST /webhooks/endpoints`), signed with `x-infitech-signature`. There is no\npolling endpoint by design.","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://infisend-api.infi-tech.cloud"}],"components":{"securitySchemes":{"session":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Dashboard session token from POST /auth/login."},"apiKey":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"An API key: sk_live_… or sk_test_…. Send-only, scoped, rate-limited."}},"schemas":{"AdminPlatformSettings":{"type":"object","properties":{"settings":{"type":"array","items":{"type":"object","properties":{"value":{"nullable":true,"type":"string"},"source":{"type":"string","enum":["STORED","ENVIRONMENT","DEFAULT"]},"key":{"type":"string","enum":["BULK_SEND_MAX_RECIPIENTS","WALLET_MIN_LIVE_BALANCE_DEFAULT","EMAIL_MAX_RECIPIENTS_PER_MESSAGE"]},"label":{"type":"string"},"description":{"type":"string"},"fallback":{"type":"object","properties":{"value":{"nullable":true,"type":"string"},"source":{"type":"string","enum":["STORED","ENVIRONMENT","DEFAULT"]}},"required":["value","source"],"additionalProperties":false},"updatedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedByEmail":{"nullable":true,"type":"string"}},"required":["value","source","key","label","description","fallback","updatedAt","updatedByEmail"],"additionalProperties":false}},"cacheTtlSeconds":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["settings","cacheTtlSeconds"],"additionalProperties":false},"AdminPlatformSettingUpdate":{"anyOf":[{"type":"object","properties":{"key":{"type":"string","enum":["BULK_SEND_MAX_RECIPIENTS"]},"value":{"nullable":true,"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["key","value","reason"],"additionalProperties":false},{"type":"object","properties":{"key":{"type":"string","enum":["WALLET_MIN_LIVE_BALANCE_DEFAULT"]},"value":{"anyOf":[{"type":"string"},{"type":"number"}]},"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["key","value","reason"],"additionalProperties":false},{"type":"object","properties":{"key":{"type":"string","enum":["EMAIL_MAX_RECIPIENTS_PER_MESSAGE"]},"value":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["key","value","reason"],"additionalProperties":false},{"type":"object","properties":{"key":{"type":"string","enum":["BULK_SEND_MAX_RECIPIENTS","WALLET_MIN_LIVE_BALANCE_DEFAULT","EMAIL_MAX_RECIPIENTS_PER_MESSAGE"]},"clear":{"type":"boolean","enum":[true]},"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["key","clear","reason"],"additionalProperties":false}]},"AdminAccountList":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"ownerEmail":{"type":"string"},"walletBalance":{},"totalSpendMtd":{},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","status","ownerEmail","walletBalance","totalSpendMtd","createdAt"],"additionalProperties":false}},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991}},"required":["accounts","total","page","pageSize"],"additionalProperties":false},"AdminAccountDetail":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"ownerUserId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","ownerUserId","status","createdAt"],"additionalProperties":false},"ownerEmail":{"type":"string"},"wallet":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"balance":{},"minLiveBalance":{}},"required":["id","accountId","balance","minLiveBalance"],"additionalProperties":false},"kycHistory":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["INDIVIDUAL","BUSINESS"]},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"submittedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reviewedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reviewerEmail":{"nullable":true,"type":"string"},"rejectionReason":{"nullable":true,"type":"string"}},"required":["id","type","status","submittedAt","reviewedAt","reviewerEmail","rejectionReason"],"additionalProperties":false}},"apiKeys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"keyPrefix":{"type":"string"},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","environment","status","keyPrefix","lastUsedAt"],"additionalProperties":false}},"recentMessages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"to":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","channel","status","to","createdAt"],"additionalProperties":false}}},"required":["account","ownerEmail","wallet","kycHistory","apiKeys","recentMessages"],"additionalProperties":false},"AdminAccountStatusChange":{"type":"object","properties":{"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"SmsSendRequest":{"type":"object","properties":{"to":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"message":{"type":"string","minLength":1,"maxLength":10000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"senderId":{"type":"string","minLength":3,"maxLength":11,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]*$"},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255}},"required":["to"]},"SendAccepted":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"channel":{"type":"string","enum":["SMS","EMAIL"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"recipients":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"kind":{"type":"string","enum":["TO","CC","BCC"]},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","CANCELLED"]}},"required":["address","kind","status"],"additionalProperties":false}},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"estimatedCost":{},"duplicate":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["messageId","status","channel","to","recipientCount","recipients","environment","estimatedCost","duplicate","createdAt"],"additionalProperties":false},"EmailSendRequest":{"type":"object","properties":{"to":{"anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"minItems":1,"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}]},"cc":{"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc":{"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"mode":{"type":"string","enum":["SHARED","INDIVIDUAL"]},"subject":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\r\\n]*$"},"text":{"type":"string","minLength":1,"maxLength":200000},"html":{"type":"string","minLength":1,"maxLength":500000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"replyTo":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"from":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"fromName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^\\r\\n]+$"},"attachments":{"not":{}},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255}},"required":["to"]},"SmsBulkSendRequest":{"type":"object","properties":{"recipients":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},{"type":"object","properties":{"to":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}}},"required":["to"]}]}},"recipientsCsv":{"type":"string","minLength":1,"maxLength":2000000},"message":{"type":"string","minLength":1,"maxLength":10000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"senderId":{"type":"string","minLength":3,"maxLength":11,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]*$"},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255}}},"BulkSendAccepted":{"type":"object","properties":{"batchId":{"type":"string","minLength":1,"maxLength":64},"batchSize":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalCost":{},"duplicate":{"type":"boolean"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"messages":{"type":"array","items":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"channel":{"type":"string","enum":["SMS","EMAIL"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"recipients":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"kind":{"type":"string","enum":["TO","CC","BCC"]},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","CANCELLED"]}},"required":["address","kind","status"],"additionalProperties":false}},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"estimatedCost":{},"duplicate":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["messageId","status","channel","to","recipientCount","recipients","environment","estimatedCost","duplicate","createdAt"],"additionalProperties":false}},"suppressedRecipients":{"type":"array","items":{"type":"object","properties":{"recipient":{"type":"string"},"reason":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]},"suppressedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["recipient","reason","suppressedAt"],"additionalProperties":false}}},"required":["batchId","batchSize","totalCost","duplicate","channel","environment","scheduledFor","messages","suppressedRecipients"],"additionalProperties":false},"EmailBulkSendRequest":{"type":"object","properties":{"recipients":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"object","properties":{"to":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}}},"required":["to"]}]}},"recipientsCsv":{"type":"string","minLength":1,"maxLength":2000000},"mode":{"type":"string","enum":["INDIVIDUAL"]},"cc":{"not":{}},"bcc":{"not":{}},"subject":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\r\\n]*$"},"text":{"type":"string","minLength":1,"maxLength":200000},"html":{"type":"string","minLength":1,"maxLength":500000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"replyTo":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"from":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"fromName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^\\r\\n]+$"},"attachments":{"not":{}},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255}}},"Message":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt"],"additionalProperties":false},"MessagePage":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["messages","nextCursor"],"additionalProperties":false},"MessageWithEngagement":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"kind":{"type":"string","enum":["TO","CC","BCC"]},"address":{"type":"string"},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","CANCELLED"]},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","kind","address","status","failureCode","failureReason","sentAt","deliveredAt"],"additionalProperties":false}},"engagement":{"type":"object","properties":{"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"firstOpenedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"openCount":{"nullable":true,"type":"integer","minimum":0,"maximum":9007199254740991},"clickCount":{"nullable":true,"type":"integer","minimum":0,"maximum":9007199254740991},"clickedLinks":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"clickedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["url","clickedAt"],"additionalProperties":false}},"caveats":{"type":"array","items":{"type":"string","enum":["Open figures include Apple Mail Privacy Protection pre-fetches, which load the tracking image whether or not a person opened the email. Treat opens as an upper bound and a directional engagement signal, not a count of human reads.","Click figures can include automated link checks by mailbox security scanners.","Opens and clicks are only measurable in HTML email. Plain-text email can never register either, so it lowers these figures.","Email has no delivery receipt: an email counts as delivered once the receiving mail server accepted it and it has not bounced.","Rates describe messages created in the window. An open or click counts toward its message’s window even if it happened later.","SMS has no open or click signal; those figures are null for SMS."]}}},"required":["deliveredAt","firstOpenedAt","openCount","clickCount","clickedLinks","caveats"],"additionalProperties":false}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt","recipients","engagement"],"additionalProperties":false},"MessageEventList":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":64},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"messageId":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["DELIVERED","OPENED","CLICKED","BOUNCED","COMPLAINED"]},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"metadata":{}},"required":["id","messageId","accountId","type","timestamp","createdAt","metadata"],"additionalProperties":false}}},"required":["messageId","events"],"additionalProperties":false},"AdminMessagePage":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"accountName":{"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"provider":{"type":"string","enum":["AFRICAS_TALKING","SMTP"]},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"from":{"type":"string"},"costCharged":{"nullable":true},"failureCode":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","accountName","channel","provider","environment","status","to","recipientCount","from","costCharged","failureCode","createdAt","sentAt","deliveredAt"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["messages","nextCursor"],"additionalProperties":false},"AdminMessageDetail":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt"],"additionalProperties":false},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"kind":{"type":"string","enum":["TO","CC","BCC"]},"address":{"type":"string"},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","CANCELLED"]},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","kind","address","status","failureCode","failureReason","sentAt","deliveredAt"],"additionalProperties":false}},"fromName":{"nullable":true,"type":"string"},"replyTo":{"nullable":true,"type":"string"},"enqueuedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"provider":{"type":"object","properties":{"provider":{"type":"string","enum":["AFRICAS_TALKING","SMTP"]},"providerMessageId":{"nullable":true,"type":"string"},"providerCost":{"nullable":true},"providerCostRaw":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"returnPathDomain":{"nullable":true,"type":"string"}},"required":["provider","providerMessageId","providerCost","providerCostRaw","failureCode","failureReason","returnPathDomain"],"additionalProperties":false},"statusHistory":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"at":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"detail":{"nullable":true,"type":"string"}},"required":["status","at","detail"],"additionalProperties":false}},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"messageId":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["DELIVERED","OPENED","CLICKED","BOUNCED","COMPLAINED"]},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"metadata":{}},"required":["id","messageId","accountId","type","timestamp","createdAt","metadata"],"additionalProperties":false}},"charges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"walletId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["TOPUP","DEBIT","REFUND","ADJUSTMENT"]},"amount":{},"balanceAfter":{},"referenceType":{"nullable":true,"type":"string"},"referenceId":{"nullable":true,"type":"string"},"paymentProvider":{"nullable":true,"type":"string","enum":["PAYCHANGU","INFI_PAY","MANUAL"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","walletId","type","amount","balanceAfter","referenceType","referenceId","paymentProvider","createdAt"],"additionalProperties":false}},"webhookDeliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"webhookEndpointId":{"type":"string","minLength":1,"maxLength":64},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"payload":{},"responseStatus":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"responseBody":{"nullable":true,"type":"string"},"attempt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["PENDING","DELIVERED","FAILED"]},"nextAttemptAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","webhookEndpointId","messageId","payload","responseStatus","responseBody","attempt","status","nextAttemptAt","createdAt"],"additionalProperties":false}},"account":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"ownerEmail":{"nullable":true,"type":"string"}},"required":["id","name","status","ownerEmail"],"additionalProperties":false}},"required":["message","recipients","fromName","replyTo","enqueuedAt","provider","statusHistory","events","charges","webhookDeliveries","account"],"additionalProperties":false},"WalletSummary":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"balance":{},"minLiveBalance":{},"meetsLiveThreshold":{"type":"boolean"}},"required":["id","accountId","balance","minLiveBalance","meetsLiveThreshold"],"additionalProperties":false},"MinLiveBalanceUpdate":{"type":"object","properties":{"minLiveBalance":{"anyOf":[{"type":"string"},{"type":"number"}]},"note":{"type":"string","minLength":5,"maxLength":1000}},"required":["minLiveBalance","note"],"additionalProperties":false},"WalletAdjustRequest":{"type":"object","properties":{"amount":{"anyOf":[{"type":"string"},{"type":"number"}]},"note":{"type":"string","minLength":5,"maxLength":1000}},"required":["amount","note"],"additionalProperties":false},"LiveKeyEligibility":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":64},"accountStatus":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"balance":{},"minLiveBalance":{},"eligible":{"type":"boolean"},"reason":{"nullable":true,"type":"string"}},"required":["accountId","accountStatus","balance","minLiveBalance","eligible","reason"],"additionalProperties":false},"WalletTransactionPage":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"walletId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["TOPUP","DEBIT","REFUND","ADJUSTMENT"]},"amount":{},"balanceAfter":{},"referenceType":{"nullable":true,"type":"string"},"referenceId":{"nullable":true,"type":"string"},"paymentProvider":{"nullable":true,"type":"string","enum":["PAYCHANGU","INFI_PAY","MANUAL"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","walletId","type","amount","balanceAfter","referenceType","referenceId","paymentProvider","createdAt"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["transactions","nextCursor"],"additionalProperties":false},"ApiKeyList":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revokedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revocationReason":{"nullable":true,"type":"string"}},"required":["id","accountId","name","keyPrefix","environment","scopes","status","lastUsedAt","createdAt","revokedAt","revocationReason"],"additionalProperties":false}}},"required":["keys"],"additionalProperties":false},"AdminApiKeyRevoke":{"type":"object","properties":{"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revokedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revocationReason":{"nullable":true,"type":"string"}},"required":["id","accountId","name","keyPrefix","environment","scopes","status","lastUsedAt","createdAt","revokedAt","revocationReason"],"additionalProperties":false},"ApiKeyCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}}},"required":["name","environment","scopes"],"additionalProperties":false},"ApiKeyWithSecret":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revokedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revocationReason":{"nullable":true,"type":"string"},"secret":{"type":"string"}},"required":["id","accountId","name","keyPrefix","environment","scopes","status","lastUsedAt","createdAt","revokedAt","revocationReason","secret"],"additionalProperties":false},"ApiKeyRotate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"scopes":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}}},"additionalProperties":false},"ApiKeyRotation":{"type":"object","properties":{"created":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revokedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revocationReason":{"nullable":true,"type":"string"},"secret":{"type":"string"}},"required":["id","accountId","name","keyPrefix","environment","scopes","status","lastUsedAt","createdAt","revokedAt","revocationReason","secret"],"additionalProperties":false},"replaced":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revokedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"revocationReason":{"nullable":true,"type":"string"}},"required":["id","accountId","name","keyPrefix","environment","scopes","status","lastUsedAt","createdAt","revokedAt","revocationReason"],"additionalProperties":false}},"required":["created","replaced"],"additionalProperties":false},"ApiKeyIdentity":{"type":"object","properties":{"accountId":{"type":"string","minLength":1,"maxLength":64},"accountName":{"type":"string"},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"keyPrefix":{"type":"string"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scopes":{"type":"array","items":{"type":"string","enum":["SMS","EMAIL","READ_ONLY"]}},"lastUsedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["accountId","accountName","apiKeyId","keyPrefix","environment","scopes","lastUsedAt"],"additionalProperties":false},"EngagementAnalytics":{"type":"object","properties":{"from":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"to":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"channel":{"nullable":true,"type":"string","enum":["SMS","EMAIL"]},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"attemptedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredEmailCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"openedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"clickedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveryRate":{"nullable":true,"type":"string"},"openRate":{"nullable":true,"type":"string"},"clickRate":{"nullable":true,"type":"string"},"caveats":{"type":"array","items":{"type":"string","enum":["Open figures include Apple Mail Privacy Protection pre-fetches, which load the tracking image whether or not a person opened the email. Treat opens as an upper bound and a directional engagement signal, not a count of human reads.","Click figures can include automated link checks by mailbox security scanners.","Opens and clicks are only measurable in HTML email. Plain-text email can never register either, so it lowers these figures.","Email has no delivery receipt: an email counts as delivered once the receiving mail server accepted it and it has not bounced.","Rates describe messages created in the window. An open or click counts toward its message’s window even if it happened later.","SMS has no open or click signal; those figures are null for SMS."]}}},"required":["from","to","environment","channel","messageCount","attemptedCount","deliveredCount","deliveredEmailCount","openedCount","clickedCount","deliveryRate","openRate","clickRate","caveats"],"additionalProperties":false},"AdminAuditLogPage":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"actorUserId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"actorEmail":{"nullable":true,"type":"string"},"action":{"type":"string"},"targetType":{"type":"string"},"targetId":{"type":"string"},"metadata":{},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","actorUserId","actorEmail","action","targetType","targetId","metadata","createdAt"],"additionalProperties":false}},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991}},"required":["entries","total","page","pageSize"],"additionalProperties":false},"SignupRequest":{"type":"object","properties":{"accountName":{"type":"string","minLength":2,"maxLength":120},"email":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"password":{"type":"string","minLength":8}},"required":["accountName","email","password"],"additionalProperties":false},"AuthSession":{"type":"object","properties":{"accessToken":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"user":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"email":{"type":"string"},"role":{"type":"string","enum":["SUPER_ADMIN","CLIENT"]},"accountId":{"type":"string","minLength":1,"maxLength":64},"isVerified":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","role","accountId","isVerified","createdAt"],"additionalProperties":false},"account":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"ownerUserId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","ownerUserId","status","createdAt"],"additionalProperties":false}},"required":["accessToken","expiresIn","user","account"],"additionalProperties":false},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"password":{"type":"string","minLength":1}},"required":["email","password"],"additionalProperties":false},"LoginResponse":{"oneOf":[{"type":"object","properties":{"accessToken":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"user":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"email":{"type":"string"},"role":{"type":"string","enum":["SUPER_ADMIN","CLIENT"]},"accountId":{"type":"string","minLength":1,"maxLength":64},"isVerified":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","role","accountId","isVerified","createdAt"],"additionalProperties":false},"account":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"ownerUserId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","ownerUserId","status","createdAt"],"additionalProperties":false},"status":{"type":"string","enum":["SESSION"]}},"required":["accessToken","expiresIn","user","account","status"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","enum":["TWO_FACTOR_REQUIRED"]},"challengeToken":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["status","challengeToken","expiresIn"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","enum":["TWO_FACTOR_SETUP_REQUIRED"]},"setupToken":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["status","setupToken","expiresIn"],"additionalProperties":false}]},"PasswordResetRequest":{"type":"object","properties":{"email":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["email"],"additionalProperties":false},"PasswordResetAcknowledgement":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]}},"required":["accepted"],"additionalProperties":false},"PasswordResetConfirm":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":200},"password":{"type":"string","minLength":8}},"required":["token","password"],"additionalProperties":false},"AuthenticatedUser":{"type":"object","properties":{"userId":{"type":"string","minLength":1,"maxLength":64},"email":{"type":"string"},"role":{"type":"string","enum":["SUPER_ADMIN","CLIENT"]},"accountId":{"type":"string","minLength":1,"maxLength":64},"accountStatus":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]}},"required":["userId","email","role","accountId","accountStatus"],"additionalProperties":false},"AdminProviderConfigList":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["AFRICAS_TALKING","SMTP","INFI_PAY"]},"name":{"type":"string"},"role":{"type":"string"},"consumedBy":{"type":"string","enum":["API","WORKER"]},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"isSecret":{"type":"boolean"},"preview":{"nullable":true,"type":"string"},"source":{"type":"string","enum":["STORED","ENVIRONMENT","UNSET"]},"updatedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedByEmail":{"nullable":true,"type":"string"}},"required":["key","label","isSecret","preview","source","updatedAt","updatedByEmail"],"additionalProperties":false}}},"required":["provider","name","role","consumedBy","fields"],"additionalProperties":false}}},"required":["providers"],"additionalProperties":false},"AdminProviderCredentialUpdate":{"type":"object","properties":{"value":{"type":"string","minLength":1,"maxLength":4096},"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["value","reason"],"additionalProperties":false},"AdminProviderCredentialDelete":{"type":"object","properties":{"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"TwoFactorStatus":{"type":"object","properties":{"enabled":{"type":"boolean"},"enabledAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"recoveryCodesRemaining":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["enabled","enabledAt","recoveryCodesRemaining"],"additionalProperties":false},"TwoFactorSetupRequest":{"type":"object","properties":{"setupToken":{"type":"string","minLength":1,"maxLength":200}},"required":["setupToken"],"additionalProperties":false},"TwoFactorSetup":{"type":"object","properties":{"setupToken":{"type":"string"},"secret":{"type":"string"},"otpauthUri":{"type":"string"},"qrCodeDataUrl":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["setupToken","secret","otpauthUri","qrCodeDataUrl","expiresIn"],"additionalProperties":false},"TwoFactorSetupVerify":{"type":"object","properties":{"setupToken":{"type":"string","minLength":1,"maxLength":200},"code":{"type":"string","pattern":"^\\d{6}$"}},"required":["setupToken","code"],"additionalProperties":false},"TwoFactorEnrollment":{"type":"object","properties":{"recoveryCodes":{"type":"array","items":{"type":"string"}},"session":{"type":"object","properties":{"accessToken":{"type":"string"},"expiresIn":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"user":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"email":{"type":"string"},"role":{"type":"string","enum":["SUPER_ADMIN","CLIENT"]},"accountId":{"type":"string","minLength":1,"maxLength":64},"isVerified":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","email","role","accountId","isVerified","createdAt"],"additionalProperties":false},"account":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"ownerUserId":{"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["PENDING_KYC","ACTIVE","SUSPENDED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","ownerUserId","status","createdAt"],"additionalProperties":false}},"required":["accessToken","expiresIn","user","account"],"additionalProperties":false}},"required":["recoveryCodes","session"],"additionalProperties":false},"TwoFactorVerify":{"type":"object","properties":{"challengeToken":{"type":"string","minLength":1,"maxLength":200},"code":{"type":"string","pattern":"^\\d{6}$"},"recoveryCode":{"type":"string","minLength":1,"maxLength":32}},"required":["challengeToken"],"additionalProperties":false},"TwoFactorSensitiveAction":{"type":"object","properties":{"password":{"type":"string","minLength":1},"code":{"type":"string","pattern":"^\\d{6}$"},"recoveryCode":{"type":"string","minLength":1,"maxLength":32}},"required":["password"],"additionalProperties":false},"TwoFactorRecoveryCodes":{"type":"object","properties":{"recoveryCodes":{"type":"array","items":{"type":"string"}}},"required":["recoveryCodes"],"additionalProperties":false},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string"},"version":{"type":"string"},"uptimeSeconds":{"type":"number","minimum":0},"correlationId":{"type":"string"}},"required":["status","service","version","uptimeSeconds","correlationId"],"additionalProperties":false},"KycSubmissionSummaryList":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["INDIVIDUAL","BUSINESS"]},"idDocumentUrl":{"type":"string"},"businessRegDocumentUrl":{"nullable":true,"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"submittedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reviewedByUserId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"reviewedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"rejectionReason":{"nullable":true,"type":"string"},"accountName":{"type":"string"}},"required":["id","accountId","type","idDocumentUrl","businessRegDocumentUrl","status","submittedAt","reviewedByUserId","reviewedAt","rejectionReason","accountName"],"additionalProperties":false}},"KycSubmissionForReview":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["INDIVIDUAL","BUSINESS"]},"idDocumentUrl":{"type":"string"},"businessRegDocumentUrl":{"nullable":true,"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"submittedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reviewedByUserId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"reviewedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"rejectionReason":{"nullable":true,"type":"string"},"accountName":{"type":"string"},"documents":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["ID","BUSINESS_REGISTRATION"]},"objectKey":{"type":"string"},"contentType":{"type":"string","enum":["application/pdf","image/jpeg","image/png"]},"downloadUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["kind","objectKey","contentType","downloadUrl","expiresAt"],"additionalProperties":false}}},"required":["id","accountId","type","idDocumentUrl","businessRegDocumentUrl","status","submittedAt","reviewedByUserId","reviewedAt","rejectionReason","accountName","documents"],"additionalProperties":false},"KycApprovalRequest":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}},"additionalProperties":false},"KycSubmissionSummary":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["INDIVIDUAL","BUSINESS"]},"idDocumentUrl":{"type":"string"},"businessRegDocumentUrl":{"nullable":true,"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"submittedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reviewedByUserId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"reviewedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"rejectionReason":{"nullable":true,"type":"string"},"accountName":{"type":"string"}},"required":["id","accountId","type","idDocumentUrl","businessRegDocumentUrl","status","submittedAt","reviewedByUserId","reviewedAt","rejectionReason","accountName"],"additionalProperties":false},"KycRejectionRequest":{"type":"object","properties":{"reason":{"type":"string","minLength":10,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"KycUploadTargetRequest":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["ID"]},"contentType":{"type":"string","enum":["image/jpeg","image/png"]}},"required":["kind","contentType"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["BUSINESS_REGISTRATION"]},"contentType":{"type":"string","enum":["application/pdf","image/jpeg","image/png"]}},"required":["kind","contentType"],"additionalProperties":false}]},"KycUploadTarget":{"type":"object","properties":{"uploadUrl":{"type":"string","format":"uri"},"formFields":{"type":"object","additionalProperties":{"type":"string"}},"objectKey":{"type":"string","minLength":1,"maxLength":512,"pattern":"^kyc\\/[A-Za-z0-9_-]+\\/[A-Za-z0-9_-]+\\.[A-Za-z0-9]+$"},"maxBytes":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["uploadUrl","formFields","objectKey","maxBytes","expiresAt"],"additionalProperties":false},"KycSubmissionRequest":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["INDIVIDUAL"]},"idDocumentKey":{"type":"string","minLength":1,"maxLength":512,"allOf":[{"type":"string","pattern":"^kyc\\/[A-Za-z0-9_-]+\\/[A-Za-z0-9_-]+\\.[A-Za-z0-9]+$"},{"type":"string","pattern":"\\.(jpg|png)$"}]}},"required":["type","idDocumentKey"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["BUSINESS"]},"idDocumentKey":{"type":"string","minLength":1,"maxLength":512,"allOf":[{"type":"string","pattern":"^kyc\\/[A-Za-z0-9_-]+\\/[A-Za-z0-9_-]+\\.[A-Za-z0-9]+$"},{"type":"string","pattern":"\\.(jpg|png)$"}]},"businessRegDocumentKey":{"type":"string","minLength":1,"maxLength":512,"pattern":"^kyc\\/[A-Za-z0-9_-]+\\/[A-Za-z0-9_-]+\\.[A-Za-z0-9]+$"}},"required":["type","idDocumentKey","businessRegDocumentKey"],"additionalProperties":false}]},"PricingRuleList":{"type":"object","properties":{"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"route":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"specificity":{"type":"string","enum":["NETWORK","COUNTRY","CHANNEL"]},"unitCost":{},"effectiveFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdByUserId":{"type":"string","minLength":1,"maxLength":64},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"status":{"type":"string","enum":["EFFECTIVE","SCHEDULED","SUPERSEDED"]}},"required":["id","route","specificity","unitCost","effectiveFrom","createdByUserId","createdAt","status"],"additionalProperties":false}}},"required":["rules"],"additionalProperties":false},"PricingCoverageList":{"type":"object","properties":{"coverage":{"type":"array","items":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"hasFallback":{"type":"boolean"},"fallbackUnitCost":{"nullable":true},"covered":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string","minLength":1,"maxLength":64},"route":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"specificity":{"type":"string","enum":["NETWORK","COUNTRY","CHANNEL"]},"unitCost":{},"effectiveFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["ruleId","route","specificity","unitCost","effectiveFrom"],"additionalProperties":false}},"gap":{"nullable":true,"type":"string"}},"required":["channel","hasFallback","fallbackUnitCost","covered","gap"],"additionalProperties":false}}},"required":["coverage"],"additionalProperties":false},"PriceResolution":{"oneOf":[{"type":"object","properties":{"priced":{"type":"boolean","enum":[true]},"route":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"unitCost":{},"ruleId":{"type":"string","minLength":1,"maxLength":64},"matched":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"specificity":{"type":"string","enum":["NETWORK","COUNTRY","CHANNEL"]},"effectiveFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"resolvedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["priced","route","unitCost","ruleId","matched","specificity","effectiveFrom","resolvedAt"],"additionalProperties":false},{"type":"object","properties":{"priced":{"type":"boolean","enum":[false]},"route":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"resolvedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reason":{"type":"string"}},"required":["priced","route","resolvedAt","reason"],"additionalProperties":false}]},"PricingRuleCreate":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"default":null,"nullable":true,"type":"string","pattern":"^[A-Z]{2}$"},"network":{"default":null,"nullable":true,"type":"string","maxLength":40,"pattern":"^[A-Z0-9]+(?:_[A-Z0-9]+)*$"},"unitCost":{"anyOf":[{"type":"string"},{"type":"number"}]},"effectiveFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["channel","unitCost"],"additionalProperties":false},"PricingRuleSummary":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"route":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"country":{"nullable":true,"type":"string"},"network":{"nullable":true,"type":"string"}},"required":["channel","country","network"],"additionalProperties":false},"specificity":{"type":"string","enum":["NETWORK","COUNTRY","CHANNEL"]},"unitCost":{},"effectiveFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdByUserId":{"type":"string","minLength":1,"maxLength":64},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"status":{"type":"string","enum":["EFFECTIVE","SCHEDULED","SUPERSEDED"]}},"required":["id","route","specificity","unitCost","effectiveFrom","createdByUserId","createdAt","status"],"additionalProperties":false},"PublicRateCard":{"type":"object","properties":{"sms":{"type":"object","properties":{"tnm":{"nullable":true},"airtel":{"nullable":true},"international":{"nullable":true}},"required":["tnm","airtel","international"],"additionalProperties":false},"email":{"nullable":true},"resolvedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["sms","email","resolvedAt"],"additionalProperties":false},"TemplateList":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"subject":{"nullable":true,"type":"string"},"body":{"type":"string"},"variables":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","name","channel","subject","body","variables","createdAt","updatedAt"],"additionalProperties":false}}},"required":["templates"],"additionalProperties":false},"Template":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"subject":{"nullable":true,"type":"string"},"body":{"type":"string"},"variables":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","name","channel","subject","body","variables","createdAt","updatedAt"],"additionalProperties":false},"TemplateCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"channel":{"type":"string","enum":["SMS","EMAIL"]},"subject":{"type":"string","minLength":1,"maxLength":255},"body":{"type":"string","minLength":1,"maxLength":500000}},"required":["name","channel","body"]},"TemplateUpdate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"subject":{"type":"string","minLength":1,"maxLength":255},"body":{"type":"string","minLength":1,"maxLength":500000}}},"AdminSenderDomainList":{"type":"object","properties":{"senderDomains":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"domain":{"type":"string"},"accountId":{"type":"string","minLength":1,"maxLength":64},"accountName":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"failureReason":{"nullable":true,"type":"string"},"suspension":{"nullable":true,"type":"object","properties":{"suspendedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reason":{"type":"string"}},"required":["suspendedAt","reason"],"additionalProperties":false},"returnPathVerified":{"type":"boolean"},"recordChecks":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string","enum":["VERIFICATION","DKIM","RETURN_PATH","SPF","DMARC"]},"requiredForVerification":{"type":"boolean"},"lastCheck":{"nullable":true,"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]}},"required":["purpose","requiredForVerification","lastCheck"],"additionalProperties":false}},"lastCheckedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verifiedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"bounces":{"type":"object","properties":{"windowDays":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"sentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"bouncedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"bounceRate":{"nullable":true,"type":"string"}},"required":["windowDays","sentCount","bouncedCount","bounceRate"],"additionalProperties":false}},"required":["id","domain","accountId","accountName","status","failureReason","suspension","returnPathVerified","recordChecks","lastCheckedAt","createdAt","verifiedAt","bounces"],"additionalProperties":false}},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991}},"required":["senderDomains","total","page","pageSize"],"additionalProperties":false},"AdminSenderDomainDetail":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"domain":{"type":"string"},"accountId":{"type":"string","minLength":1,"maxLength":64},"accountName":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"failureReason":{"nullable":true,"type":"string"},"suspension":{"nullable":true,"type":"object","properties":{"suspendedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reason":{"type":"string"}},"required":["suspendedAt","reason"],"additionalProperties":false},"returnPathVerified":{"type":"boolean"},"recordChecks":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string","enum":["VERIFICATION","DKIM","RETURN_PATH","SPF","DMARC"]},"requiredForVerification":{"type":"boolean"},"lastCheck":{"nullable":true,"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]}},"required":["purpose","requiredForVerification","lastCheck"],"additionalProperties":false}},"lastCheckedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verifiedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"bounces":{"type":"object","properties":{"windowDays":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"sentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"bouncedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"bounceRate":{"nullable":true,"type":"string"}},"required":["windowDays","sentCount","bouncedCount","bounceRate"],"additionalProperties":false},"dkimSelector":{"type":"string"},"returnPathDomain":{"type":"string"},"records":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string","enum":["VERIFICATION","DKIM","RETURN_PATH","SPF","DMARC"]},"type":{"type":"string","enum":["TXT","CNAME"]},"host":{"type":"string"},"value":{"type":"string"},"valueChunks":{"nullable":true,"type":"array","items":{"type":"string"}},"requiredForVerification":{"type":"boolean"},"lastCheck":{"nullable":true,"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"note":{"type":"string"}},"required":["purpose","type","host","value","valueChunks","requiredForVerification","lastCheck","note"],"additionalProperties":false}},"lastCheck":{"nullable":true,"type":"object","properties":{"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verification":{"nullable":true,"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"dkim":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"returnPath":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false}},"required":["checkedAt","verification","dkim","returnPath"],"additionalProperties":false},"checkHistory":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"trigger":{"type":"string","enum":["CLIENT_VERIFY","SCHEDULED_RECHECK","ADMIN_RECHECK"]},"statusBefore":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"statusAfter":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"result":{"nullable":true,"type":"object","properties":{"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verification":{"nullable":true,"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"dkim":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"returnPath":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false}},"required":["checkedAt","verification","dkim","returnPath"],"additionalProperties":false}},"required":["id","checkedAt","trigger","statusBefore","statusAfter","result"],"additionalProperties":false}},"inFlightMessages":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","domain","accountId","accountName","status","failureReason","suspension","returnPathVerified","recordChecks","lastCheckedAt","createdAt","verifiedAt","bounces","dkimSelector","returnPathDomain","records","lastCheck","checkHistory","inFlightMessages"],"additionalProperties":false},"AdminSenderDomainAction":{"type":"object","properties":{"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"SenderDomainCreate":{"type":"object","properties":{"domain":{"type":"string"}},"required":["domain"]},"SenderDomain":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"domain":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"suspension":{"nullable":true,"type":"object","properties":{"suspendedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reason":{"type":"string"}},"required":["suspendedAt","reason"],"additionalProperties":false},"dkimSelector":{"type":"string"},"returnPathDomain":{"type":"string"},"returnPathVerified":{"type":"boolean"},"failureReason":{"nullable":true,"type":"string"},"records":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string","enum":["VERIFICATION","DKIM","RETURN_PATH","SPF","DMARC"]},"type":{"type":"string","enum":["TXT","CNAME"]},"host":{"type":"string"},"value":{"type":"string"},"valueChunks":{"nullable":true,"type":"array","items":{"type":"string"}},"requiredForVerification":{"type":"boolean"},"lastCheck":{"nullable":true,"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"note":{"type":"string"}},"required":["purpose","type","host","value","valueChunks","requiredForVerification","lastCheck","note"],"additionalProperties":false}},"lastCheckedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"lastCheck":{"nullable":true,"type":"object","properties":{"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verification":{"nullable":true,"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"dkim":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"returnPath":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false}},"required":["checkedAt","verification","dkim","returnPath"],"additionalProperties":false},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verifiedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","domain","status","suspension","dkimSelector","returnPathDomain","returnPathVerified","failureReason","records","lastCheckedAt","lastCheck","createdAt","verifiedAt"],"additionalProperties":false},"SenderDomainList":{"type":"object","properties":{"senderDomains":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"domain":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFIED","FAILED"]},"suspension":{"nullable":true,"type":"object","properties":{"suspendedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"reason":{"type":"string"}},"required":["suspendedAt","reason"],"additionalProperties":false},"dkimSelector":{"type":"string"},"returnPathDomain":{"type":"string"},"returnPathVerified":{"type":"boolean"},"failureReason":{"nullable":true,"type":"string"},"records":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string","enum":["VERIFICATION","DKIM","RETURN_PATH","SPF","DMARC"]},"type":{"type":"string","enum":["TXT","CNAME"]},"host":{"type":"string"},"value":{"type":"string"},"valueChunks":{"nullable":true,"type":"array","items":{"type":"string"}},"requiredForVerification":{"type":"boolean"},"lastCheck":{"nullable":true,"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"note":{"type":"string"}},"required":["purpose","type","host","value","valueChunks","requiredForVerification","lastCheck","note"],"additionalProperties":false}},"lastCheckedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"lastCheck":{"nullable":true,"type":"object","properties":{"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verification":{"nullable":true,"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"dkim":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false},"returnPath":{"type":"object","properties":{"outcome":{"type":"string","enum":["MATCH","MISSING","MISMATCH","LOOKUP_FAILED"]},"detail":{"type":"string"}},"required":["outcome","detail"],"additionalProperties":false}},"required":["checkedAt","verification","dkim","returnPath"],"additionalProperties":false},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"verifiedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","domain","status","suspension","dkimSelector","returnPathDomain","returnPathVerified","failureReason","records","lastCheckedAt","lastCheck","createdAt","verifiedAt"],"additionalProperties":false}}},"required":["senderDomains"],"additionalProperties":false},"SenderDomainRevoked":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"domain":{"type":"string"},"inFlightMessages":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","domain","inFlightMessages"],"additionalProperties":false},"SuppressionList":{"type":"object","properties":{"suppressions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"destination":{"type":"string"},"reason":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]},"evidence":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","channel","destination","reason","evidence","createdAt"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["suppressions","nextCursor"],"additionalProperties":false},"SuppressionCreate":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"destination":{"type":"string","minLength":1,"maxLength":320},"reason":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]},"evidence":{"type":"string","maxLength":500}},"required":["channel","destination","reason"]},"Suppression":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"destination":{"type":"string"},"reason":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]},"evidence":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","channel","destination","reason","evidence","createdAt"],"additionalProperties":false},"SendLimits":{"type":"object","properties":{"maxRecipients":{"nullable":true,"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"maxRequestBodyBytes":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991}},"required":["maxRecipients","maxRequestBodyBytes"],"additionalProperties":false},"DashboardSmsSendRequest":{"type":"object","properties":{"to":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"message":{"type":"string","minLength":1,"maxLength":10000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"senderId":{"type":"string","minLength":3,"maxLength":11,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]*$"},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255},"environment":{"default":"SANDBOX","type":"string","enum":["SANDBOX","LIVE"]}},"required":["to"]},"DashboardEmailSendRequest":{"type":"object","properties":{"to":{"anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"minItems":1,"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}]},"cc":{"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"bcc":{"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"mode":{"type":"string","enum":["SHARED","INDIVIDUAL"]},"subject":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\r\\n]*$"},"text":{"type":"string","minLength":1,"maxLength":200000},"html":{"type":"string","minLength":1,"maxLength":500000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"replyTo":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"from":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"fromName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^\\r\\n]+$"},"attachments":{"not":{}},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255},"environment":{"default":"SANDBOX","type":"string","enum":["SANDBOX","LIVE"]}},"required":["to"]},"DashboardSmsBulkSendRequest":{"type":"object","properties":{"recipients":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},{"type":"object","properties":{"to":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}}},"required":["to"]}]}},"recipientsCsv":{"type":"string","minLength":1,"maxLength":2000000},"message":{"type":"string","minLength":1,"maxLength":10000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"senderId":{"type":"string","minLength":3,"maxLength":11,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]*$"},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255},"environment":{"default":"SANDBOX","type":"string","enum":["SANDBOX","LIVE"]}}},"DashboardEmailBulkSendRequest":{"type":"object","properties":{"recipients":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"object","properties":{"to":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}}},"required":["to"]}]}},"recipientsCsv":{"type":"string","minLength":1,"maxLength":2000000},"mode":{"type":"string","enum":["INDIVIDUAL"]},"cc":{"not":{}},"bcc":{"not":{}},"subject":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^\\r\\n]*$"},"text":{"type":"string","minLength":1,"maxLength":200000},"html":{"type":"string","minLength":1,"maxLength":500000},"templateId":{"type":"string","minLength":1,"maxLength":64},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}},"replyTo":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"from":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"fromName":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[^\\r\\n]+$"},"attachments":{"not":{}},"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"type":"string","minLength":8,"maxLength":255},"environment":{"default":"SANDBOX","type":"string","enum":["SANDBOX","LIVE"]}}},"ScheduledMessageList":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt"],"additionalProperties":false}}},"required":["messages"],"additionalProperties":false},"BulkSendPreviewRequest":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"recipients":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","minLength":1,"maxLength":320},{"type":"object","properties":{"to":{"type":"string","minLength":1,"maxLength":320},"variables":{"type":"object","additionalProperties":{"type":"string","maxLength":2000}}},"required":["to"]}]}},"recipientsCsv":{"type":"string","minLength":1,"maxLength":2000000}},"required":["channel"]},"BulkSendPreview":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"recipientCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalCost":{},"balance":{},"sufficientBalance":{"type":"boolean"},"invalidRecipients":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991},"recipient":{"type":"string"},"reason":{"type":"string"}},"required":["index","recipient","reason"],"additionalProperties":false}},"unpricedRoutes":{"type":"array","items":{"type":"object","properties":{"route":{"type":"string"},"reason":{"type":"string"}},"required":["route","reason"],"additionalProperties":false}},"suppressedRecipients":{"type":"array","items":{"type":"object","properties":{"recipient":{"type":"string"},"reason":{"type":"string","enum":["USER_STOP","USER_UNSUBSCRIBE","PROVIDER_REPORTED"]},"suppressedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["recipient","reason","suppressedAt"],"additionalProperties":false}}},"required":["channel","recipientCount","totalCost","balance","sufficientBalance","invalidRecipients","unpricedRoutes","suppressedRecipients"],"additionalProperties":false},"MessageWithRecipients":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"apiKeyId":{"type":"string","minLength":1,"maxLength":64},"channel":{"type":"string","enum":["SMS","EMAIL"]},"direction":{"type":"string","enum":["OUTBOUND"]},"to":{"type":"string"},"recipientCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"batchId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"from":{"type":"string"},"subject":{"nullable":true,"type":"string"},"body":{"nullable":true,"type":"string"},"templateId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]},"providerMessageId":{"nullable":true,"type":"string"},"costCharged":{"nullable":true},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"scheduledFor":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"idempotencyKey":{"nullable":true,"type":"string"},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"kind":{"type":"string","enum":["TO","CC","BCC"]},"address":{"type":"string"},"status":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","CANCELLED"]},"failureCode":{"nullable":true,"type":"string"},"failureReason":{"nullable":true,"type":"string"},"sentAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"deliveredAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","kind","address","status","failureCode","failureReason","sentAt","deliveredAt"],"additionalProperties":false}}},"required":["id","accountId","apiKeyId","channel","direction","to","recipientCount","batchId","from","subject","body","templateId","status","providerMessageId","costCharged","environment","scheduledFor","idempotencyKey","failureCode","failureReason","createdAt","sentAt","deliveredAt","recipients"],"additionalProperties":false},"AdminRevenueReport":{"type":"object","properties":{"granularity":{"type":"string","enum":["DAY","WEEK","MONTH"]},"from":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"to":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"totals":{"type":"object","properties":{"topUps":{},"clientCharge":{},"providerCost":{},"grossMargin":{},"marginPercent":{"nullable":true,"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"costedMessageCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["topUps","clientCharge","providerCost","grossMargin","marginPercent","messageCount","costedMessageCount"],"additionalProperties":false},"periods":{"type":"array","items":{"type":"object","properties":{"topUps":{},"clientCharge":{},"providerCost":{},"grossMargin":{},"marginPercent":{"nullable":true,"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"costedMessageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"label":{"type":"string"}},"required":["topUps","clientCharge","providerCost","grossMargin","marginPercent","messageCount","costedMessageCount","start","end","label"],"additionalProperties":false}},"topAccounts":{"type":"array","items":{"type":"object","properties":{"topUps":{},"clientCharge":{},"providerCost":{},"grossMargin":{},"marginPercent":{"nullable":true,"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"costedMessageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"accountId":{"type":"string","minLength":1,"maxLength":64},"accountName":{"type":"string"}},"required":["topUps","clientCharge","providerCost","grossMargin","marginPercent","messageCount","costedMessageCount","accountId","accountName"],"additionalProperties":false}}},"required":["granularity","from","to","totals","periods","topAccounts"],"additionalProperties":false},"AdminSystemHealth":{"type":"object","properties":{"status":{"type":"string","enum":["OK","DEGRADED","DOWN"]},"problems":{"type":"array","items":{"type":"string"}},"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"dependencies":{"type":"object","properties":{"postgres":{"type":"object","properties":{"ok":{"type":"boolean"},"latencyMs":{"nullable":true,"type":"number","minimum":0},"error":{"nullable":true,"type":"string"}},"required":["ok","latencyMs","error"],"additionalProperties":false},"redis":{"type":"object","properties":{"ok":{"type":"boolean"},"latencyMs":{"nullable":true,"type":"number","minimum":0},"error":{"nullable":true,"type":"string"}},"required":["ok","latencyMs","error"],"additionalProperties":false}},"required":["postgres","redis"],"additionalProperties":false},"queues":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"]},"paused":{"nullable":true,"type":"boolean"},"counts":{"nullable":true,"type":"object","properties":{"waiting":{"type":"integer","minimum":0,"maximum":9007199254740991},"active":{"type":"integer","minimum":0,"maximum":9007199254740991},"delayed":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991},"completed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["waiting","active","delayed","failed","completed"],"additionalProperties":false},"oldestWaitingAgeSeconds":{"nullable":true,"type":"number","minimum":0},"backlogged":{"type":"boolean"},"error":{"nullable":true,"type":"string"}},"required":["name","paused","counts","oldestWaitingAgeSeconds","backlogged","error"],"additionalProperties":false}},"workers":{"type":"object","properties":{"alive":{"type":"boolean"},"instances":{"type":"array","items":{"type":"object","properties":{"instanceId":{"type":"string"},"hostname":{"type":"string"},"pid":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string"},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"lastBeatAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"secondsSinceBeat":{"type":"number","minimum":0},"stale":{"type":"boolean"}},"required":["instanceId","hostname","pid","version","startedAt","lastBeatAt","secondsSinceBeat","stale"],"additionalProperties":false}},"error":{"nullable":true,"type":"string"}},"required":["alive","instances","error"],"additionalProperties":false},"circuitBreakers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"environment":{"type":"string","enum":["SANDBOX","LIVE"]},"state":{"type":"string","enum":["CLOSED","OPEN","HALF_OPEN"]},"instances":{"type":"array","items":{"type":"object","properties":{"instanceId":{"type":"string"},"state":{"type":"string","enum":["CLOSED","OPEN","HALF_OPEN"]},"lastChangedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["instanceId","state","lastChangedAt"],"additionalProperties":false}}},"required":["provider","channel","environment","state","instances"],"additionalProperties":false}},"backlogWarnSeconds":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["status","problems","checkedAt","dependencies","queues","workers","circuitBreakers","backlogWarnSeconds"],"additionalProperties":false},"AdminFailedJobPage":{"type":"object","properties":{"queue":{"type":"string","enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"]},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"accountId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"failedReason":{"type":"string"},"attemptsMade":{"type":"integer","minimum":0,"maximum":9007199254740991},"maxAttempts":{"nullable":true,"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},"addedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"failedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"stacktrace":{"nullable":true,"type":"string"}},"required":["id","name","messageId","accountId","failedReason","attemptsMade","maxAttempts","addedAt","failedAt","stacktrace"],"additionalProperties":false}},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["queue","jobs","total","page","pageSize"],"additionalProperties":false},"AdminFailedJobAction":{"type":"object","properties":{"reason":{"type":"string","minLength":5,"maxLength":1000}},"required":["reason"],"additionalProperties":false},"AdminFailedJobActionResult":{"type":"object","properties":{"queue":{"type":"string","enum":["sms.send","email.send","sandbox.delivery-report","webhook.deliver"]},"jobId":{"type":"string"},"action":{"type":"string","enum":["RETRIED","DISCARDED"]},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"messageStatus":{"nullable":true,"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","REJECTED","CANCELLED","PARTIALLY_FAILED"]}},"required":["queue","jobId","action","messageId","messageStatus"],"additionalProperties":false},"AdminOverview":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"messages":{"type":"object","properties":{"today":{"type":"object","properties":{"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"attemptedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveryRate":{"nullable":true,"type":"string"},"from":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"to":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"byChannel":{"type":"array","items":{"type":"object","properties":{"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"attemptedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveryRate":{"nullable":true,"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]}},"required":["messageCount","attemptedCount","deliveredCount","failedCount","deliveryRate","channel"],"additionalProperties":false}}},"required":["messageCount","attemptedCount","deliveredCount","failedCount","deliveryRate","from","to","byChannel"],"additionalProperties":false},"last7Days":{"type":"object","properties":{"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"attemptedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveryRate":{"nullable":true,"type":"string"},"from":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"to":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"byChannel":{"type":"array","items":{"type":"object","properties":{"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"attemptedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveryRate":{"nullable":true,"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]}},"required":["messageCount","attemptedCount","deliveredCount","failedCount","deliveryRate","channel"],"additionalProperties":false}}},"required":["messageCount","attemptedCount","deliveredCount","failedCount","deliveryRate","from","to","byChannel"],"additionalProperties":false},"trend":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"label":{"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"deliveredCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"byChannel":{"type":"array","items":{"type":"object","properties":{"channel":{"type":"string","enum":["SMS","EMAIL"]},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["channel","messageCount"],"additionalProperties":false}}},"required":["start","end","label","messageCount","deliveredCount","byChannel"],"additionalProperties":false}}},"required":["today","last7Days","trend"],"additionalProperties":false},"kyc":{"type":"object","properties":{"pendingCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"oldestPendingAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["pendingCount","oldestPendingAt"],"additionalProperties":false},"wallets":{"type":"object","properties":{"belowMinLiveBalanceCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"activeAccountCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["belowMinLiveBalanceCount","activeAccountCount"],"additionalProperties":false},"system":{"type":"object","properties":{"status":{"type":"string","enum":["OK","DEGRADED","DOWN"]},"problemCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedJobCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"unreadableQueueCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"workersAlive":{"type":"boolean"},"unhealthyBreakers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"channel":{"type":"string","enum":["SMS","EMAIL"]},"state":{"type":"string","enum":["CLOSED","OPEN","HALF_OPEN"]}},"required":["provider","channel","state"],"additionalProperties":false}}},"required":["status","problemCount","failedJobCount","unreadableQueueCount","workersAlive","unhealthyBreakers"],"additionalProperties":false},"revenue":{"type":"object","properties":{"thisMonth":{"type":"object","properties":{"topUps":{},"clientCharge":{},"providerCost":{},"grossMargin":{},"marginPercent":{"nullable":true,"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"costedMessageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"label":{"type":"string"}},"required":["topUps","clientCharge","providerCost","grossMargin","marginPercent","messageCount","costedMessageCount","start","end","label"],"additionalProperties":false},"lastMonth":{"type":"object","properties":{"topUps":{},"clientCharge":{},"providerCost":{},"grossMargin":{},"marginPercent":{"nullable":true,"type":"string"},"messageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"costedMessageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"label":{"type":"string"}},"required":["topUps","clientCharge","providerCost","grossMargin","marginPercent","messageCount","costedMessageCount","start","end","label"],"additionalProperties":false},"clientChargeChangePercent":{"nullable":true,"type":"string"}},"required":["thisMonth","lastMonth","clientChargeChangePercent"],"additionalProperties":false},"accounts":{"type":"object","properties":{"suspendedCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"recentSuspensions":{"type":"array","items":{"type":"object","properties":{"auditLogId":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string"},"accountName":{"nullable":true,"type":"string"},"reason":{"nullable":true,"type":"string"},"actorEmail":{"nullable":true,"type":"string"},"suspendedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"stillSuspended":{"type":"boolean"}},"required":["auditLogId","accountId","accountName","reason","actorEmail","suspendedAt","stillSuspended"],"additionalProperties":false}}},"required":["suspendedCount","recentSuspensions"],"additionalProperties":false},"recentAuditEntries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"actorUserId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"actorEmail":{"nullable":true,"type":"string"},"action":{"type":"string"},"targetType":{"type":"string"},"targetId":{"type":"string"},"metadata":{},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","actorUserId","actorEmail","action","targetType","targetId","metadata","createdAt"],"additionalProperties":false}}},"required":["generatedAt","messages","kyc","wallets","system","revenue","accounts","recentAuditEntries"],"additionalProperties":false},"TopupRequest":{"type":"object","properties":{"amount":{"anyOf":[{"type":"string"},{"type":"number"}]},"provider":{"type":"string","enum":["AIRTEL","MPAMBA"]},"phoneNumber":{"type":"string"}},"required":["amount","provider","phoneNumber"],"additionalProperties":false},"TopupInitiation":{"type":"object","properties":{"reference":{"type":"string"},"provider":{"type":"string","enum":["AIRTEL","MPAMBA"]},"phoneNumber":{"type":"string"},"amount":{},"status":{"type":"string","enum":["PENDING","SUCCESSFUL","FAILED"]}},"required":["reference","provider","phoneNumber","amount","status"],"additionalProperties":false},"TopupStatusResult":{"type":"object","properties":{"reference":{"type":"string"},"status":{"type":"string","enum":["PENDING","SUCCESSFUL","FAILED"]},"amount":{"nullable":true},"creditedAmount":{"nullable":true},"updatedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["reference","status","amount","creditedAmount","updatedAt"],"additionalProperties":false},"WebhookEndpointList":{"type":"object","properties":{"endpoints":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["ACTIVE","DISABLED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","url","events","status","createdAt","updatedAt"],"additionalProperties":false}}},"required":["endpoints"],"additionalProperties":false},"WebhookEndpointCreate":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"events":{"default":[],"maxItems":9,"type":"array","items":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","message.rejected","message.cancelled","message.partially_failed","message.recipient.failed","message.recipient.delivered"]}}},"required":["url"]},"WebhookEndpointWithSecret":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["ACTIVE","DISABLED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"secret":{"type":"string"}},"required":["id","accountId","url","events","status","createdAt","updatedAt","secret"],"additionalProperties":false},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"accountId":{"type":"string","minLength":1,"maxLength":64},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["ACTIVE","DISABLED"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","accountId","url","events","status","createdAt","updatedAt"],"additionalProperties":false},"WebhookEndpointUpdate":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"events":{"maxItems":9,"type":"array","items":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","message.rejected","message.cancelled","message.partially_failed","message.recipient.failed","message.recipient.delivered"]}},"status":{"type":"string","enum":["ACTIVE","DISABLED"]}}},"WebhookDeliveryPage":{"type":"object","properties":{"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"webhookEndpointId":{"type":"string","minLength":1,"maxLength":64},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"payload":{},"responseStatus":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"responseBody":{"nullable":true,"type":"string"},"attempt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["PENDING","DELIVERED","FAILED"]},"nextAttemptAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","webhookEndpointId","messageId","payload","responseStatus","responseBody","attempt","status","nextAttemptAt","createdAt"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["deliveries","nextCursor"],"additionalProperties":false},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"webhookEndpointId":{"type":"string","minLength":1,"maxLength":64},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"payload":{},"responseStatus":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"responseBody":{"nullable":true,"type":"string"},"attempt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["PENDING","DELIVERED","FAILED"]},"nextAttemptAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","webhookEndpointId","messageId","payload","responseStatus","responseBody","attempt","status","nextAttemptAt","createdAt"],"additionalProperties":false},"WebhookResendAccepted":{"type":"object","properties":{"webhookEndpointId":{"type":"string","minLength":1,"maxLength":64},"messageId":{"nullable":true,"type":"string","minLength":1,"maxLength":64},"event":{"type":"string"},"maxAttempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["webhookEndpointId","messageId","event","maxAttempts"],"additionalProperties":false}}}}