{"openapi":"3.1.0","info":{"title":"Brivo Switchgear","version":"1.0.0","description":"One API for messaging, USSD and verification. Every request made with an API key counts against that key's rate limit, per minute (by default 1200 in sandbox and staging, 6000 in production; each message of a batch counts as one). Over it, the answer is 429 `rate_limited` with `Retry-After`. Every response carries `X-Request-Id`: yours when you send one (1–128 letters, digits and `. _ : -`), else one we make. Quote it to Brivo support; webhook deliveries that follow from the request carry it too."},"servers":[{"url":"https://sandbox.switchgear.app","description":"Sandbox (sg_test_ keys)"},{"url":"https://api.switchgear.app","description":"Production (sg_live_ keys)"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"sg_live_… or sg_test_…"}},"schemas":{"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_failed","idempotency_key_missing","unauthenticated","insufficient_balance","insufficient_scope","account_suspended","mfa_required","ip_not_allowed","approval_required","limit_reached","sandbox_only","not_found","evidence_link_invalid","idempotency_conflict","invalid_transition","edit_conflict","suppressed_destination","whatsapp_number_taken","whatsapp_signup_failed","sender_id_not_approved","no_route","outside_service_window","media_not_found","unsupported_media_type","budget_exceeded","push_app_not_registered","push_config_mismatch","template_not_found","template_not_approved","ussd_flow_invalid","ussd_shortcode_taken","ussd_shortcode_in_use","ussd_session_ended","ussd_adapter_restricted","ussd_mode_unavailable","promo_code_refused","margin_guard","payload_too_large","rate_limited","internal_error","dependency_unavailable"]},"message":{"type":"string"},"details":{}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"EndUssdSessionRequest":{"default":{},"type":"object","properties":{"text":{"type":"string","maxLength":182}}},"EndUssdSessionResponse":{"type":"object","properties":{"session_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","const":"ended"},"reason":{"type":"string","enum":["user_end","app_end","app_timeout","app_error","telco_timeout","telco_error","redis_unavailable","api_end"]}},"required":["session_id","status","reason"],"additionalProperties":false},"UssdEmulatorRequest":{"type":"object","properties":{"dial":{"type":"string","pattern":"^\\*[\\d*]+#$"},"session":{"type":"string","minLength":1,"maxLength":100},"input":{"type":"string","maxLength":182},"msisdn":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$"},"network":{"type":"string","pattern":"^\\d{5,6}$"}}},"UssdEmulatorResponse":{"type":"object","properties":{"session":{"type":"string"},"msisdn":{"type":"string"},"text":{"type":"string"},"end":{"type":"boolean"}},"required":["session","msisdn","text","end"],"additionalProperties":false},"UssdCallbackRequest":{"type":"object","properties":{"session_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"msisdn":{"type":"string"},"shortcode":{"type":"string"},"step":{"type":"integer","minimum":0,"maximum":9007199254740991},"input":{"type":"string"},"state":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"network":{"type":["string","null"]},"environment":{"type":"string","enum":["sandbox","staging","production"]}},"required":["session_id","msisdn","shortcode","step","input","state","network","environment"],"additionalProperties":false},"UssdCallbackResponse":{"type":"object","properties":{"text":{"type":"string","maxLength":2000},"action":{"type":"string","enum":["continue","end"]},"state":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["text","action"]},"UssdSessionStartedData":{"type":"object","properties":{"session_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"shortcode_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"shortcode":{"type":"string"},"msisdn":{"type":"string"},"network":{"type":["string","null"]},"provider":{"type":"string"},"started_at":{"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":["session_id","shortcode_id","shortcode","msisdn","network","provider","started_at"],"additionalProperties":false},"UssdSessionEndedData":{"type":"object","properties":{"session_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"shortcode_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"shortcode":{"type":"string"},"msisdn":{"type":"string"},"network":{"type":["string","null"]},"provider":{"type":"string"},"started_at":{"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","enum":["user_end","app_end","app_timeout","app_error","telco_timeout","telco_error","redis_unavailable","api_end"]},"steps":{"type":"integer","minimum":0,"maximum":9007199254740991},"ended_at":{"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))$"},"duration_ms":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["session_id","shortcode_id","shortcode","msisdn","network","provider","started_at","reason","steps","ended_at","duration_ms"],"additionalProperties":false},"UssdScreenTruncatedData":{"type":"object","properties":{"session_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"shortcode_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"step":{"type":"integer","minimum":0,"maximum":9007199254740991},"length":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["session_id","shortcode_id","step","length","limit"],"additionalProperties":false},"Me":{"type":"object","properties":{"key_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"organisation_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"environment_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"environment":{"type":"string","enum":["sandbox","staging","production"]},"scopes":{"type":"array","items":{"type":"string","enum":["messages:send","messages:read","otp:send","otp:verify","verifications:create","verifications:read","ussd:manage","templates:read","templates:write","suppressions:write","usage:read","push:devices","push:manage","webhooks:manage","inbound:read"]}}},"required":["key_id","organisation_id","project_id","environment_id","environment","scopes"],"additionalProperties":false},"RotateApiKeyRequest":{"type":"object","properties":{"overlap_hours":{"default":24,"type":"integer","minimum":0,"maximum":168},"name":{"type":"string","minLength":2,"maxLength":60}}},"RotateApiKeyResponse":{"type":"object","properties":{"api_key":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["messages:send","messages:read","otp:send","otp:verify","verifications:create","verifications:read","ussd:manage","templates:read","templates:write","suppressions:write","usage:read","push:devices","push:manage","webhooks:manage","inbound:read"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"created_at":{"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))$"},"created_by_email":{"type":["string","null"]},"last_used_at":{"anyOf":[{"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))$"},{"type":"null"}]},"expires_at":{"anyOf":[{"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))$"},{"type":"null"}]},"revoked_at":{"anyOf":[{"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))$"},{"type":"null"}]},"replaced_by_key_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["id","name","prefix","scopes","status","created_at","created_by_email","last_used_at","expires_at","revoked_at","replaced_by_key_id"],"additionalProperties":false},"key":{"type":"string"},"previous":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["messages:send","messages:read","otp:send","otp:verify","verifications:create","verifications:read","ussd:manage","templates:read","templates:write","suppressions:write","usage:read","push:devices","push:manage","webhooks:manage","inbound:read"]}},"status":{"type":"string","enum":["active","expired","revoked"]},"created_at":{"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))$"},"created_by_email":{"type":["string","null"]},"last_used_at":{"anyOf":[{"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))$"},{"type":"null"}]},"expires_at":{"anyOf":[{"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))$"},{"type":"null"}]},"revoked_at":{"anyOf":[{"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))$"},{"type":"null"}]},"replaced_by_key_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["id","name","prefix","scopes","status","created_at","created_by_email","last_used_at","expires_at","revoked_at","replaced_by_key_id"],"additionalProperties":false}},"required":["api_key","key","previous"],"additionalProperties":false},"SendMessageRequest":{"type":"object","properties":{"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"to":{"type":"string","minLength":1},"template":{"type":"string","pattern":"^[a-z0-9][a-z0-9_.-]{0,63}$"},"variables":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1024}},"locale":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Z]{2})?$"},"body":{"type":"string","minLength":1},"subject":{"type":"string","minLength":1,"maxLength":255},"html":{"type":"string","minLength":1},"sender_id":{"type":"string"},"tags":{"maxItems":10,"type":"array","items":{"type":"string"}},"schedule_at":{"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":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"push":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"image":{"type":"string","maxLength":2048,"format":"uri"},"deep_link":{"type":"string","minLength":1,"maxLength":2048},"data":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,64}$"},"additionalProperties":{"type":"string","maxLength":1024}},"priority":{"default":"high","type":"string","enum":["high","normal"]},"ttl":{"type":"integer","minimum":0,"maximum":2419200},"collapse_key":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,64}$"},"badge":{"type":"integer","minimum":0,"maximum":99999},"sound":{"type":"string","minLength":1,"maxLength":64},"android_channel_id":{"type":"string","minLength":1,"maxLength":64},"silent":{"default":false,"type":"boolean"},"fallback":{"type":"object","properties":{"sms":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"html":{"type":"string","minLength":1}}}}},"whatsapp":{"type":"object","properties":{"media":{"type":"object","properties":{"kind":{"type":"string","enum":["image","document","audio","video"]},"url":{"type":"string","maxLength":2048,"format":"uri"},"media_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"filename":{"type":"string","minLength":1,"maxLength":240}},"required":["kind"]}}}},"required":["channel","to"]},"Message":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"status":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"cost_units":{"type":["number","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"scheduled_at":{"anyOf":[{"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))$"},{"type":"null"}]},"created_at":{"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","provider","provider_ref","cost_units","metadata","scheduled_at","created_at"],"additionalProperties":false},"MessageDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"status":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"cost_units":{"type":["number","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"scheduled_at":{"anyOf":[{"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))$"},{"type":"null"}]},"created_at":{"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))$"},"events":{"type":"array","items":{"type":"object","properties":{"event":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"raw_code":{"type":["string","null"]},"reason":{"type":["string","null"]},"occurred_at":{"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":["event","provider","provider_ref","raw_code","reason","occurred_at"],"additionalProperties":false}}},"required":["id","channel","status","provider","provider_ref","cost_units","metadata","scheduled_at","created_at","events"],"additionalProperties":false},"SendMessageBatchRequest":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","minItems":1,"maxItems":1000,"items":{"$ref":"#/components/schemas/SendMessageRequest"},"description":"Each item is a `POST /v1/messages` body, validated on its own."}}},"MessageBatchResponse":{"type":"object","properties":{"accepted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991},"message":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"status":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"cost_units":{"type":["number","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"scheduled_at":{"anyOf":[{"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))$"},{"type":"null"}]},"created_at":{"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","provider","provider_ref","cost_units","metadata","scheduled_at","created_at"],"additionalProperties":false},"replayed":{"type":"boolean"}},"required":["index","message","replayed"],"additionalProperties":false},{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_failed","idempotency_key_missing","unauthenticated","insufficient_balance","insufficient_scope","account_suspended","mfa_required","ip_not_allowed","approval_required","limit_reached","sandbox_only","not_found","evidence_link_invalid","idempotency_conflict","invalid_transition","edit_conflict","suppressed_destination","whatsapp_number_taken","whatsapp_signup_failed","sender_id_not_approved","no_route","outside_service_window","media_not_found","unsupported_media_type","budget_exceeded","push_app_not_registered","push_config_mismatch","template_not_found","template_not_approved","ussd_flow_invalid","ussd_shortcode_taken","ussd_shortcode_in_use","ussd_session_ended","ussd_adapter_restricted","ussd_mode_unavailable","promo_code_refused","margin_guard","payload_too_large","rate_limited","internal_error","dependency_unavailable"]},"message":{"type":"string"},"details":{}},"required":["code","message"],"additionalProperties":false}},"required":["index","error"],"additionalProperties":false}]}}},"required":["accepted","failed","results"],"additionalProperties":false},"MessageList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"status":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"cost_units":{"type":["number","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"scheduled_at":{"anyOf":[{"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))$"},{"type":"null"}]},"created_at":{"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))$"},"destination_hint":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"updated_at":{"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","provider","provider_ref","cost_units","metadata","scheduled_at","created_at","destination_hint","tags","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"Usage":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"currency":{"type":"string"},"rows":{"type":"array","items":{"type":"object","properties":{"channel":{"type":"string","enum":["sms","email","whatsapp","push","ussd","verification"]},"provider":{"type":"string"},"unit_type":{"type":"string","enum":["sms_segment","email","whatsapp_message","push_notification","verification","ussd_session"]},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"units":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amount_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["channel","provider","unit_type","count","units","amount_minor"],"additionalProperties":false}},"totals":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"units":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amount_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["count","units","amount_minor"],"additionalProperties":false}},"required":["period","currency","rows","totals"],"additionalProperties":false},"PackageBalance":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"definition_key":{"type":"string"},"name":{"type":"string"},"period":{"type":"string","enum":["monthly","quarterly","half_yearly","yearly"]},"months":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"bonus_bp":{"type":"integer","minimum":0,"maximum":5000},"price_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"charged_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string"},"allowances":{"type":"object","properties":{"sms":{"type":"object","properties":{"granted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"carried":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["granted","remaining","carried"],"additionalProperties":false},"whatsapp":{"type":"object","properties":{"granted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"carried":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["granted","remaining","carried"],"additionalProperties":false},"email":{"type":"object","properties":{"granted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"carried":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["granted","remaining","carried"],"additionalProperties":false}},"required":["sms","whatsapp","email"],"additionalProperties":false},"starts_at":{"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))$"},"expires_at":{"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":["active","used_up","expired","queued","replaced","cancelled"]},"source":{"type":"string","enum":["purchase","grant","welcome"]},"change":{"anyOf":[{"type":"string","enum":["upgrade","carry_over","queue"]},{"type":"null"}]},"previous_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"promo_code":{"type":["string","null"]},"discount_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"promotion_cost_minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created_at":{"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","definition_key","name","period","months","bonus_bp","price_minor","charged_minor","currency","allowances","starts_at","expires_at","status","source","change","previous_id","promo_code","discount_minor","promotion_cost_minor","created_at"],"additionalProperties":false}},"remaining":{"type":"object","properties":{"sms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"whatsapp":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["sms","whatsapp","email"],"additionalProperties":false}},"required":["data","remaining"],"additionalProperties":false},"CreateTemplateRequest":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9][a-z0-9_.-]{0,63}$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"locale":{"default":"en","type":"string","pattern":"^[a-z]{2,3}(-[A-Z]{2})?$"},"body":{"type":"string","minLength":1,"maxLength":4096},"subject":{"type":"string","minLength":1,"maxLength":255},"html":{"type":"string","minLength":1},"description":{"type":"string","maxLength":500},"category":{"type":"string","enum":["UTILITY","MARKETING","AUTHENTICATION"]},"examples":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","minLength":1,"maxLength":200}},"header":{"type":"object","properties":{"format":{"type":"string","enum":["image","document","video"]},"sample_media_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["format","sample_media_id"]}},"required":["key","channel","body"]},"Template":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"key":{"type":"string"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"locale":{"type":"string"},"description":{"type":["string","null"]},"version":{"type":"integer","minimum":1,"maximum":9007199254740991},"version_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"body":{"type":"string"},"subject":{"type":["string","null"]},"html":{"type":["string","null"]},"variables":{"type":"array","items":{"type":"string"}},"approval_state":{"type":"string","enum":["pending","approved","rejected","paused"]},"category":{"anyOf":[{"type":"string","enum":["UTILITY","MARKETING","AUTHENTICATION"]},{"type":"null"}]},"header_format":{"anyOf":[{"type":"string","enum":["image","document","video"]},{"type":"null"}]},"created_at":{"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))$"},"updated_at":{"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","key","channel","locale","description","version","version_id","body","subject","html","variables","approval_state","category","header_format","created_at","updated_at"],"additionalProperties":false},"TemplateList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"key":{"type":"string"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"locale":{"type":"string"},"description":{"type":["string","null"]},"version":{"type":"integer","minimum":1,"maximum":9007199254740991},"version_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"body":{"type":"string"},"subject":{"type":["string","null"]},"html":{"type":["string","null"]},"variables":{"type":"array","items":{"type":"string"}},"approval_state":{"type":"string","enum":["pending","approved","rejected","paused"]},"category":{"anyOf":[{"type":"string","enum":["UTILITY","MARKETING","AUTHENTICATION"]},{"type":"null"}]},"header_format":{"anyOf":[{"type":"string","enum":["image","document","video"]},{"type":"null"}]},"created_at":{"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))$"},"updated_at":{"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","key","channel","locale","description","version","version_id","body","subject","html","variables","approval_state","category","header_format","created_at","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"SendOtpRequest":{"type":"object","properties":{"destination":{"type":"string","minLength":1},"channel":{"default":"sms","type":"string","enum":["sms","whatsapp","email"]},"length":{"type":"integer","minimum":4,"maximum":10},"ttl":{"type":"integer","minimum":60,"maximum":3600},"template":{"type":"string","pattern":"^[a-z0-9][a-z0-9_.-]{0,63}$"},"locale":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Z]{2})?$"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["destination"]},"OtpChallenge":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","whatsapp","email"]},"status":{"type":"string","enum":["pending","verified","expired","too_many_attempts"]},"message_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expires_at":{"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))$"},"max_attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"resend_available_at":{"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":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"created_at":{"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","message_id","expires_at","max_attempts","resend_available_at","metadata","created_at"],"additionalProperties":false},"VerifyOtpRequest":{"type":"object","properties":{"challenge_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string","pattern":"^\\d{4,10}$"}},"required":["challenge_id","code"]},"VerifyOtpResponse":{"type":"object","properties":{"challenge_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"result":{"type":"string","enum":["verified","invalid_code","expired","too_many_attempts","already_verified"]},"status":{"type":"string","enum":["pending","verified","expired","too_many_attempts"]},"attempts_remaining":{"type":"integer","minimum":0,"maximum":9007199254740991},"verified_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["challenge_id","result","status","attempts_remaining","verified_at"],"additionalProperties":false},"CreateVerificationRequest":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"nrc_lookup"},"subject":{"type":"object","properties":{"nrc":{"type":"string","pattern":"^\\d{6}\\/\\d{2}\\/\\d$"},"first_name":{"type":"string","minLength":1,"maxLength":100},"last_name":{"type":"string","minLength":1,"maxLength":100},"date_of_birth":{"type":"string","format":"date","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])))$"}},"required":["nrc","first_name","last_name"]},"callback_url":{"type":"string","maxLength":2048,"format":"uri"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","subject"]},{"type":"object","properties":{"type":{"type":"string","const":"document"},"subject":{"type":"object","properties":{"document_type":{"type":"string","enum":["nrc","passport","drivers_licence"]},"front_image":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"back_image":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"content_type":{"type":"string","enum":["image/jpeg","image/png"]},"expected":{"type":"object","properties":{"document_number":{"type":"string","minLength":1,"maxLength":40},"first_name":{"type":"string","minLength":1,"maxLength":100},"last_name":{"type":"string","minLength":1,"maxLength":100},"date_of_birth":{"type":"string","format":"date","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])))$"}}}},"required":["document_type","front_image","content_type"]},"callback_url":{"type":"string","maxLength":2048,"format":"uri"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","subject"]},{"type":"object","properties":{"type":{"type":"string","const":"liveness"},"subject":{"type":"object","properties":{"frames":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"}},"challenge":{"type":"string","minLength":1,"maxLength":1024},"steps":{"minItems":2,"maxItems":3,"type":"array","items":{"type":"object","properties":{"action":{"type":"string","enum":["blink","turn_left","turn_right","smile"]},"frames":{"minItems":2,"maxItems":5,"type":"array","items":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"}},"times_ms":{"type":"array","items":{"type":"integer","minimum":0,"maximum":120000}}},"required":["action","frames","times_ms"]}},"content_type":{"type":"string","enum":["image/jpeg","image/png"]}},"required":["content_type"]},"callback_url":{"type":"string","maxLength":2048,"format":"uri"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","subject"]},{"type":"object","properties":{"type":{"type":"string","const":"face_match"},"subject":{"type":"object","properties":{"selfie":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"reference_image":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"content_type":{"type":"string","enum":["image/jpeg","image/png"]}},"required":["selfie","reference_image","content_type"]},"callback_url":{"type":"string","maxLength":2048,"format":"uri"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","subject"]},{"type":"object","properties":{"type":{"type":"string","const":"kyc_basic"},"subject":{"type":"object","properties":{"document":{"type":"object","properties":{"document_type":{"type":"string","enum":["nrc","passport","drivers_licence"]},"front_image":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"back_image":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"},"content_type":{"type":"string","enum":["image/jpeg","image/png"]},"expected":{"type":"object","properties":{"document_number":{"type":"string","minLength":1,"maxLength":40},"first_name":{"type":"string","minLength":1,"maxLength":100},"last_name":{"type":"string","minLength":1,"maxLength":100},"date_of_birth":{"type":"string","format":"date","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])))$"}}}},"required":["document_type","front_image","content_type"]},"selfie":{"type":"object","properties":{"frames":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"string","pattern":"^[A-Za-z0-9+/]+={0,2}$"}},"content_type":{"type":"string","enum":["image/jpeg","image/png"]}},"required":["frames","content_type"]},"nrc":{"type":"object","properties":{"nrc":{"type":"string","pattern":"^\\d{6}\\/\\d{2}\\/\\d$"},"first_name":{"type":"string","minLength":1,"maxLength":100},"last_name":{"type":"string","minLength":1,"maxLength":100},"date_of_birth":{"type":"string","format":"date","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])))$"}},"required":["nrc","first_name","last_name"]}},"required":["document","selfie"]},"callback_url":{"type":"string","maxLength":2048,"format":"uri"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","subject"]}]},"Verification":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["nrc_lookup","document","liveness","face_match","kyc_basic"]},"status":{"type":"string","enum":["pending","completed","failed","skipped"]},"subject":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"decision":{"anyOf":[{"type":"string","enum":["pass","review","fail"]},{"type":"null"}]},"confidence":{"type":["number","null"]},"reasons":{"type":"array","items":{"type":"string"}},"result":{"anyOf":[{"anyOf":[{"type":"object","properties":{"outcome":{"type":"string","enum":["match","partial_match","not_found"]},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["outcome","scores"],"additionalProperties":false},{"type":"object","properties":{"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"confidence":{"type":"number","minimum":0,"maximum":1},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["fields","checks","confidence","scores"],"additionalProperties":false},{"type":"object","properties":{"outcome":{"type":"string","enum":["pass","fail","inconclusive"]},"score":{"type":"number","minimum":0,"maximum":1},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"frames_analysed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["outcome","score","checks","frames_analysed"],"additionalProperties":false},{"type":"object","properties":{"similarity":{"type":"number","minimum":0,"maximum":1},"faces":{"type":"object","properties":{"selfie":{"type":"boolean"},"reference":{"type":"boolean"}},"required":["selfie","reference"],"additionalProperties":false}},"required":["similarity","faces"],"additionalProperties":false}]},{"type":"null"}]},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"steps":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["nrc_lookup","document","liveness","face_match"]},"step":{"type":"integer","minimum":0,"maximum":9007199254740991},"stop_on_fail":{"type":"boolean"},"status":{"type":"string","enum":["pending","completed","failed","skipped"]},"decision":{"anyOf":[{"type":"string","enum":["pass","review","fail"]},{"type":"null"}]},"confidence":{"type":["number","null"]},"reasons":{"type":"array","items":{"type":"string"}},"result":{"anyOf":[{"anyOf":[{"type":"object","properties":{"outcome":{"type":"string","enum":["match","partial_match","not_found"]},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["outcome","scores"],"additionalProperties":false},{"type":"object","properties":{"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"confidence":{"type":"number","minimum":0,"maximum":1},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["fields","checks","confidence","scores"],"additionalProperties":false},{"type":"object","properties":{"outcome":{"type":"string","enum":["pass","fail","inconclusive"]},"score":{"type":"number","minimum":0,"maximum":1},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"frames_analysed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["outcome","score","checks","frames_analysed"],"additionalProperties":false},{"type":"object","properties":{"similarity":{"type":"number","minimum":0,"maximum":1},"faces":{"type":"object","properties":{"selfie":{"type":"boolean"},"reference":{"type":"boolean"}},"required":["selfie","reference"],"additionalProperties":false}},"required":["similarity","faces"],"additionalProperties":false}]},{"type":"null"}]},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string","enum":["document_front","document_back","provider_response","liveness_frame","selfie","reference_photo"]},"sequence":{"type":"integer","minimum":0,"maximum":9007199254740991},"content_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"url":{"type":["string","null"]},"url_expires_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["id","kind","sequence","content_type","size_bytes","url","url_expires_at"],"additionalProperties":false}},"completed_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["id","type","step","stop_on_fail","status","decision","confidence","reasons","result","failure","provider","provider_ref","evidence","completed_at"],"additionalProperties":false}},{"type":"null"}]},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string","enum":["document_front","document_back","provider_response","liveness_frame","selfie","reference_photo"]},"sequence":{"type":"integer","minimum":0,"maximum":9007199254740991},"content_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"url":{"type":["string","null"]},"url_expires_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["id","kind","sequence","content_type","size_bytes","url","url_expires_at"],"additionalProperties":false}},"evidence_expires_at":{"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))$"},"evidence_deleted_at":{"anyOf":[{"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))$"},{"type":"null"}]},"callback_url":{"type":["string","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"created_at":{"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))$"},"completed_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["id","type","status","subject","decision","confidence","reasons","result","failure","provider","provider_ref","steps","parent_id","evidence","evidence_expires_at","evidence_deleted_at","callback_url","metadata","created_at","completed_at"],"additionalProperties":false},"LivenessChallenge":{"type":"object","properties":{"challenge":{"type":"string"},"steps":{"type":"array","items":{"type":"string","enum":["blink","turn_left","turn_right","smile"]}},"expires_at":{"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":["challenge","steps","expires_at"],"additionalProperties":false},"VerificationList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["nrc_lookup","document","liveness","face_match","kyc_basic"]},"status":{"type":"string","enum":["pending","completed","failed","skipped"]},"subject":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"decision":{"anyOf":[{"type":"string","enum":["pass","review","fail"]},{"type":"null"}]},"confidence":{"type":["number","null"]},"reasons":{"type":"array","items":{"type":"string"}},"result":{"anyOf":[{"anyOf":[{"type":"object","properties":{"outcome":{"type":"string","enum":["match","partial_match","not_found"]},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["outcome","scores"],"additionalProperties":false},{"type":"object","properties":{"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"confidence":{"type":"number","minimum":0,"maximum":1},"scores":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number","minimum":0,"maximum":1}}},"required":["fields","checks","confidence","scores"],"additionalProperties":false},{"type":"object","properties":{"outcome":{"type":"string","enum":["pass","fail","inconclusive"]},"score":{"type":"number","minimum":0,"maximum":1},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"detail":{"type":["string","null"]}},"required":["name","passed","detail"],"additionalProperties":false}},"frames_analysed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["outcome","score","checks","frames_analysed"],"additionalProperties":false},{"type":"object","properties":{"similarity":{"type":"number","minimum":0,"maximum":1},"faces":{"type":"object","properties":{"selfie":{"type":"boolean"},"reference":{"type":"boolean"}},"required":["selfie","reference"],"additionalProperties":false}},"required":["similarity","faces"],"additionalProperties":false}]},{"type":"null"}]},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"evidence_expires_at":{"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))$"},"evidence_deleted_at":{"anyOf":[{"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))$"},{"type":"null"}]},"callback_url":{"type":["string","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"created_at":{"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))$"},"completed_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["id","type","status","subject","decision","confidence","reasons","result","failure","provider","provider_ref","parent_id","evidence_expires_at","evidence_deleted_at","callback_url","metadata","created_at","completed_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"CreateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"event_types":{"default":[],"maxItems":14,"type":"array","items":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","inbound.received","otp.verified","otp.expired","verification.completed","verification.failed","ussd.session.started","ussd.session.ended","ussd.flow.event","ussd.screen.truncated","email.unsubscribed"]}},"description":{"type":"string","maxLength":500}},"required":["url"]},"CreatedWebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"event_types":{"type":"array","items":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","inbound.received","otp.verified","otp.expired","verification.completed","verification.failed","ussd.session.started","ussd.session.ended","ussd.flow.event","ussd.screen.truncated","email.unsubscribed"]}},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"created_at":{"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","url","event_types","description","enabled","created_at","secret"],"additionalProperties":false},"WebhookEndpointList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"event_types":{"type":"array","items":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","inbound.received","otp.verified","otp.expired","verification.completed","verification.failed","ussd.session.started","ussd.session.ended","ussd.flow.event","ussd.screen.truncated","email.unsubscribed"]}},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"created_at":{"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","url","event_types","description","enabled","created_at"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["message.queued","message.sent","message.delivered","message.failed","inbound.received","otp.verified","otp.expired","verification.completed","verification.failed","ussd.session.started","ussd.session.ended","ussd.flow.event","ussd.screen.truncated","email.unsubscribed"]},"created_at":{"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))$"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","type","created_at","data"],"additionalProperties":false},"SandboxInboxQuery":{"type":"object","properties":{"to":{"type":"string"},"since":{"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))$"},"limit":{"default":10,"type":"integer","minimum":1,"maximum":50}},"required":["to"]},"SandboxInbox":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"message_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"subject":{"type":["string","null"]},"body":{"type":"string"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"provider_ref":{"type":"string"},"delivered_at":{"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":["message_id","channel","subject","body","headers","provider_ref","delivered_at"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"PutPushAppRequest":{"type":"object","properties":{"route":{"type":"string","enum":["fcm","hms","apns","web"]},"identifier":{"type":"string","minLength":1,"maxLength":255},"config_file":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"vapid_subject":{"type":"string","pattern":"^(mailto:\\S+@\\S+|https:\\/\\/\\S+)$"}},"required":["route","identifier"]},"PushApp":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"route":{"type":"string","enum":["fcm","hms","apns","web"]},"platform":{"type":"string","enum":["android","ios","web"]},"identifier":{"type":"string"},"provider_project_id":{"type":["string","null"]},"provider_app_id":{"type":["string","null"]},"check":{"type":"object","properties":{"ok":{"type":["boolean","null"]},"message":{"type":"string"}},"required":["ok","message"],"additionalProperties":false},"vapid_public_key":{"type":["string","null"]},"created_at":{"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","route","platform","identifier","provider_project_id","provider_app_id","check","vapid_public_key","created_at"],"additionalProperties":false},"PushAppList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"route":{"type":"string","enum":["fcm","hms","apns","web"]},"platform":{"type":"string","enum":["android","ios","web"]},"identifier":{"type":"string"},"provider_project_id":{"type":["string","null"]},"provider_app_id":{"type":["string","null"]},"check":{"type":"object","properties":{"ok":{"type":["boolean","null"]},"message":{"type":"string"}},"required":["ok","message"],"additionalProperties":false},"vapid_public_key":{"type":["string","null"]},"created_at":{"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","route","platform","identifier","provider_project_id","provider_app_id","check","vapid_public_key","created_at"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"RegisterPushDeviceRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"maxLength":256},"app_id":{"type":"string","minLength":1,"maxLength":255},"address":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"fcm_fid"},"fid":{"type":"string","minLength":8,"maxLength":4096,"pattern":"^[\\x21-\\x7E]+$"}},"required":["kind","fid"]},{"type":"object","properties":{"kind":{"type":"string","const":"fcm_token"},"token":{"type":"string","minLength":8,"maxLength":4096,"pattern":"^[\\x21-\\x7E]+$"}},"required":["kind","token"]},{"type":"object","properties":{"kind":{"type":"string","const":"hms_token"},"token":{"type":"string","minLength":8,"maxLength":4096,"pattern":"^[\\x21-\\x7E]+$"}},"required":["kind","token"]},{"type":"object","properties":{"kind":{"type":"string","const":"apns_token"},"token":{"type":"string","pattern":"^[0-9a-fA-F]{64,200}$"},"environment":{"type":"string","enum":["development","production"]}},"required":["kind","token"]},{"type":"object","properties":{"kind":{"type":"string","const":"webpush_subscription"},"subscription":{"type":"object","properties":{"endpoint":{"type":"string","maxLength":2048,"format":"uri"},"expirationTime":{"type":["number","null"]},"keys":{"type":"object","properties":{"p256dh":{"type":"string","pattern":"^[A-Za-z0-9_-]{86,88}={0,2}$"},"auth":{"type":"string","pattern":"^[A-Za-z0-9_-]{21,24}={0,2}$"}},"required":["p256dh","auth"]}},"required":["endpoint","keys"]}},"required":["kind","subscription"]}]}},"required":["user_id","app_id","address"]},"PushDevice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"user_id":{"type":"string"},"app_id":{"type":"string"},"platform":{"type":"string","enum":["android","ios","web"]},"route":{"type":"string","enum":["fcm","hms","apns","web"]},"address_kind":{"type":"string","enum":["fcm_fid","fcm_token","hms_token","apns_token","webpush_subscription"]},"apns_environment":{"anyOf":[{"type":"string","enum":["development","production"]},{"type":"null"}]},"last_seen_at":{"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))$"},"invalidated_at":{"anyOf":[{"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))$"},{"type":"null"}]},"invalid_reason":{"type":["string","null"]},"created_at":{"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","user_id","app_id","platform","route","address_kind","apns_environment","last_seen_at","invalidated_at","invalid_reason","created_at"],"additionalProperties":false},"PushDeviceQuery":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"maxLength":256},"include_invalidated":{"default":false,"type":"boolean"},"limit":{"default":50,"type":"integer","minimum":1,"maximum":100},"cursor":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"CreateSuppressionRequest":{"type":"object","properties":{"destination":{"type":"string","minLength":1,"maxLength":320},"channel":{"default":null,"anyOf":[{"type":"string","enum":["sms","email","whatsapp","push"]},{"type":"null"}]},"reason":{"type":"string","minLength":1,"maxLength":500},"scope":{"default":"all","type":"string","enum":["all","bulk"]}},"required":["destination"]},"Suppression":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"anyOf":[{"type":"string","enum":["sms","email","whatsapp","push"]},{"type":"null"}]},"destination_masked":{"type":"string"},"destination_hint":{"type":"string"},"source":{"type":"string","enum":["api","portal","opt_out","bounce","complaint","erasure","unsubscribe"]},"scope":{"type":"string","enum":["all","bulk"]},"reason":{"type":["string","null"]},"created_at":{"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","destination_masked","destination_hint","source","scope","reason","created_at"],"additionalProperties":false},"SuppressionQuery":{"type":"object","properties":{"destination":{"type":"string","minLength":1,"maxLength":320},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"source":{"type":"string","enum":["api","portal","opt_out","bounce","complaint","erasure","unsubscribe"]},"scope":{"type":"string","enum":["all","bulk"]},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200},"cursor":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"SuppressionList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"anyOf":[{"type":"string","enum":["sms","email","whatsapp","push"]},{"type":"null"}]},"destination_masked":{"type":"string"},"destination_hint":{"type":"string"},"source":{"type":"string","enum":["api","portal","opt_out","bounce","complaint","erasure","unsubscribe"]},"scope":{"type":"string","enum":["all","bulk"]},"reason":{"type":["string","null"]},"created_at":{"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","destination_masked","destination_hint","source","scope","reason","created_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"PushDeviceList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"user_id":{"type":"string"},"app_id":{"type":"string"},"platform":{"type":"string","enum":["android","ios","web"]},"route":{"type":"string","enum":["fcm","hms","apns","web"]},"address_kind":{"type":"string","enum":["fcm_fid","fcm_token","hms_token","apns_token","webpush_subscription"]},"apns_environment":{"anyOf":[{"type":"string","enum":["development","production"]},{"type":"null"}]},"last_seen_at":{"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))$"},"invalidated_at":{"anyOf":[{"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))$"},{"type":"null"}]},"invalid_reason":{"type":["string","null"]},"created_at":{"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","user_id","app_id","platform","route","address_kind","apns_environment","last_seen_at","invalidated_at","invalid_reason","created_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"MessageEventData":{"type":"object","properties":{"message_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"status":{"type":"string","enum":["queued","sent","delivered","failed","bounced","expired"]},"tags":{"type":"array","items":{"type":"string"}},"provider":{"type":["string","null"]},"provider_ref":{"type":["string","null"]},"reason":{"type":["string","null"]},"raw_code":{"type":["string","null"]},"cost_units":{"type":["number","null"]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["message_id","channel","status","tags","provider","provider_ref","reason","raw_code","cost_units","metadata"],"additionalProperties":false},"OtpEventData":{"type":"object","properties":{"challenge_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","whatsapp","email"]},"status":{"type":"string","enum":["pending","verified","expired","too_many_attempts"]},"message_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["challenge_id","channel","status","message_id","metadata"],"additionalProperties":false},"VerificationEventData":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["nrc_lookup","document","liveness","face_match","kyc_basic"]},"status":{"type":"string","enum":["pending","completed","failed","skipped"]},"decision":{"anyOf":[{"type":"string","enum":["pass","review","fail"]},{"type":"null"}]},"confidence":{"type":["number","null"]},"reasons":{"type":"array","items":{"type":"string"}},"failure_code":{"type":["string","null"]},"provider":{"type":["string","null"]},"steps":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["nrc_lookup","document","liveness","face_match"]},"status":{"type":"string","enum":["pending","completed","failed","skipped"]},"decision":{"anyOf":[{"type":"string","enum":["pass","review","fail"]},{"type":"null"}]},"confidence":{"type":["number","null"]},"reasons":{"type":"array","items":{"type":"string"}},"failure_code":{"type":["string","null"]},"provider":{"type":["string","null"]}},"required":["verification_id","type","status","decision","confidence","reasons","failure_code","provider"],"additionalProperties":false}},{"type":"null"}]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["verification_id","type","status","decision","confidence","reasons","failure_code","provider","steps","metadata"],"additionalProperties":false},"EmailUnsubscribedEventData":{"type":"object","properties":{"message_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"suppression_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","const":"email"},"destination_hint":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"unsubscribed_at":{"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":["message_id","suppression_id","channel","destination_hint","tags","metadata","unsubscribed_at"],"additionalProperties":false},"InboundMessage":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"from":{"type":["string","null"]},"to":{"type":["string","null"]},"body":{"type":["string","null"]},"provider":{"type":"string"},"provider_ref":{"type":"string"},"matched_message_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"media":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["image","document","audio","video","sticker"]},"mime_type":{"type":"string"},"status":{"type":"string","enum":["pending","stored","too_large","unsupported","failed","expired"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"filename":{"type":["string","null"]},"caption":{"type":["string","null"]},"url":{"type":["string","null"]},"url_expires_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["kind","mime_type","status","size_bytes","filename","caption","url","url_expires_at"],"additionalProperties":false},{"type":"null"}]},"received_at":{"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","from","to","body","provider","provider_ref","matched_message_id","media","received_at"],"additionalProperties":false},"InboundList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"from":{"type":["string","null"]},"to":{"type":["string","null"]},"body":{"type":["string","null"]},"provider":{"type":"string"},"provider_ref":{"type":"string"},"matched_message_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"media":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["image","document","audio","video","sticker"]},"mime_type":{"type":"string"},"status":{"type":"string","enum":["pending","stored","too_large","unsupported","failed","expired"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"filename":{"type":["string","null"]},"caption":{"type":["string","null"]},"url":{"type":["string","null"]},"url_expires_at":{"anyOf":[{"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))$"},{"type":"null"}]}},"required":["kind","mime_type","status","size_bytes","filename","caption","url","url_expires_at"],"additionalProperties":false},{"type":"null"}]},"received_at":{"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","from","to","body","provider","provider_ref","matched_message_id","media","received_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["data","next_cursor"],"additionalProperties":false},"InboundEventData":{"type":"object","properties":{"inbound_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"channel":{"type":"string","enum":["sms","email","whatsapp","push"]},"from":{"type":"string"},"provider":{"type":"string"},"provider_ref":{"type":"string"},"matched_message_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"media_kind":{"anyOf":[{"type":"string","enum":["image","document","audio","video","sticker"]},{"type":"null"}]},"received_at":{"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":["inbound_id","channel","from","provider","provider_ref","matched_message_id","media_kind","received_at"],"additionalProperties":false},"InboundReplyRequest":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":4096},"media":{"type":"object","properties":{"kind":{"type":"string","enum":["image","document","audio","video"]},"url":{"type":"string","maxLength":2048,"format":"uri"},"media_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"filename":{"type":"string","minLength":1,"maxLength":240}},"required":["kind"]},"tags":{"maxItems":10,"type":"array","items":{"type":"string"}},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}}},"MediaObject":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string","enum":["image","document","audio","video","sticker"]},"mime_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"filename":{"type":["string","null"]},"sha256":{"type":"string"},"created_at":{"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))$"},"expires_at":{"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","mime_type","size_bytes","filename","sha256","created_at","expires_at"],"additionalProperties":false},"SandboxInboundRequest":{"type":"object","properties":{"channel":{"type":"string","const":"whatsapp"},"from":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"body":{"type":"string","minLength":1,"maxLength":4096},"media":{"type":"object","properties":{"kind":{"type":"string","enum":["image","document","audio","video","sticker"]},"mime_type":{"type":"string","maxLength":100},"size_bytes":{"type":"integer","minimum":1,"maximum":33554432},"filename":{"type":"string","minLength":1,"maxLength":240}},"required":["kind"]}},"required":["channel","from"]},"SandboxInboundResponse":{"type":"object","properties":{"provider_ref":{"type":"string"},"to":{"type":"string"}},"required":["provider_ref","to"],"additionalProperties":false}}},"security":[{"apiKey":[]}],"paths":{"/v1/me":{"get":{"summary":"The project, environment and scopes this API key resolves to","responses":{"200":{"description":"The key is valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/keys/{id}/rotate":{"post":{"summary":"Rotate this API key","description":"A key rotates itself: `id` is the calling key's id (`key_id` from `GET /v1/me`); other keys are managed in the business portal. No scope is needed. The answer holds the new key, shown once, with the same scopes and rate limit. The old key keeps working for `overlap_hours` (default 24, at most 168; 0 ends it now), so deploy the new key within that window; then it is revoked. A key can be rotated once.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateApiKeyRequest"}}}},"responses":{"201":{"description":"The new key (`key` is its plaintext, shown once) and the old one with its new `expires_at`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateApiKeyResponse"}}}},"400":{"description":"An overlap outside 0–168 hours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"`id` is not the calling key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"This key was already rotated (`invalid_transition`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/messages":{"post":{"summary":"Send one message","description":"Accepts the message once it is durably queued (scope `messages:send`). Delivery is reported through `message.*` events and `GET /v1/messages/{id}`. Send `body`, or `template` (a key) with `variables`: the newest approved version for the channel and locale is rendered, and every placeholder is required. Tag OTP messages `otp` to send them ahead of everything else, and campaigns `marketing` to send them behind. When the environment has quiet hours (business portal → Suppressions), a message tagged `marketing` that falls due inside them waits until they end in the recipient's local time; `scheduled_at` says until when. Messages also tagged `otp` or `transactional` never wait. Bulk email (tagged `marketing`, or sent in a batch unless the environment is set to marketing only) carries a one-click unsubscribe: `List-Unsubscribe` and `List-Unsubscribe-Post` headers, and a link at the foot of the email layout. An unsubscribe adds a `bulk` suppression and emits `email.unsubscribed`; email tagged `otp` or `transactional` never carries it and is never stopped by it. A push may carry `push.fallback` (`{ sms }` or `{ email }`): if it reaches no device, the same message is sent there once, as a message of its own, billed at that channel's price. The fallback must be routable when the push is accepted. WhatsApp: `whatsapp.media` sends an image, document, audio or video by https `url` or by the `media_id` of an upload (`POST /v1/media`), with `body` as its caption; with a template that has a media header, it is the header's file. Without a template, a WhatsApp message is free-form, which Meta allows only within 24 hours of the person's last message (`outside_service_window` otherwise) and which is billed as a service conversation. The simulator fails numbers ending in `00`.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"responses":{"202":{"description":"Queued. On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Invalid body (`validation_failed`) or no Idempotency-Key (`idempotency_key_missing`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Production and staging: the wallet can’t cover the estimated price (`insufficient_balance`; prepaid stops at zero, postpaid at the credit limit). Nothing is stored; top up and retry with the same Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:send`, or the account is suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"The body is over 100 KB (`payload_too_large`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"WhatsApp: the uploaded file is not a type WhatsApp sends as that kind (`unsupported_media_type`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The destination is suppressed (`suppressed_destination`), no routing rule matches (`no_route`), the template is missing (`template_not_found`) or not approved (`template_not_approved`), or the project has reached its monthly budget and the send is marketing or a batch item (`budget_exceeded`; OTP and transactional sends never are). WhatsApp: free-form outside the customer-service window (`outside_service_window`), or a `media_id` that is not an upload of this environment's or has expired (`media_not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Over the key's rate limit (`rate_limited`, with `Retry-After`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Stored but not queued; retry with the same Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"summary":"List messages","description":"Scope `messages:read`. Newest first; pass `next_cursor` as `cursor` for older messages. Never the destination or body: `destination_hint` is the tail of a keyed hash of the destination, as in the business portal, so recipients can be told apart without being shown. `GET /v1/messages/{id}` has the events.","parameters":[{"name":"status","in":"query","description":"Comma-separated, any of: queued, sent, delivered, failed, bounced, expired","schema":{"type":"string"},"example":"failed,expired"},{"name":"channel","in":"query","description":"Comma-separated, any of: sms, email, whatsapp, push","schema":{"type":"string"},"example":"sms"},{"name":"tag","in":"query","description":"Only messages sent with this tag","schema":{"type":"string","maxLength":100}},{"name":"since","in":"query","description":"Created at or after","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","description":"Created before","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"A page of messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageList"}}}},"400":{"description":"An unknown status or channel, `since` not before `until`, or a cursor that is not a message in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/messages/batch":{"post":{"summary":"Send up to 1,000 messages","description":"Scope `messages:send`. Up to 1000 items in a body of up to 5 MB, each a `POST /v1/messages` body. Every item is validated, checked against the suppression list, routed, held against the wallet and queued on its own: `results` has one entry per item, in order, with the queued message or that item's error (the codes `POST /v1/messages` would answer with), so one bad item never fails the rest. Item *i* is stored under the Idempotency-Key `<key> <i>`: resend the same batch with the same key and the items already accepted replay (`replayed: true`) while the others are tried again, so keep the items in the same order. A request-level error (below) means no item was looked at.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageBatchRequest"}}}},"responses":{"200":{"description":"Every item has a result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageBatchResponse"}}}},"400":{"description":"No `messages` array, an empty one or more than 1,000 items (`validation_failed`), or no Idempotency-Key (`idempotency_key_missing`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:send`, or the account is suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"The body is over 5 MB (`payload_too_large`); split the batch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"The batch's messages don't fit in what is left of the key's rate limit this minute (`rate_limited`, with `Retry-After`), or never could (no `Retry-After`; split it). Nothing was sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/messages/{id}":{"get":{"summary":"Current status and event history of a message","description":"Scope `messages:read`. Only messages in the API key's environment are visible.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDetail"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such message in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/templates":{"post":{"summary":"Save a template","description":"Scope `templates:write`. The first save of a key, channel and locale creates the template; each later save adds a version. Every `{{variable}}` in the body (and the email subject) is required when sending. Versions are approved on save, except WhatsApp, which waits for Meta. WhatsApp `header` gives the template a media header (`image`, `document` or `video`) with a sample file Meta's reviewers see (`sample_media_id`, an upload); each send then gives its own file in `whatsapp.media`. Category `AUTHENTICATION` takes exactly one variable, `{{code}}`: Meta sends its own text with a copy-code button, and `POST /v1/otp/send` on WhatsApp uses it.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateRequest"}}}},"responses":{"201":{"description":"The saved version. On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"400":{"description":"Invalid body or placeholders, or no Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `templates:write`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"summary":"List templates with their newest version","description":"Scope `templates:read`. Oldest first; pass `next_cursor` as `cursor` for the next page.","parameters":[{"name":"channel","in":"query","schema":{"type":"string"}},{"name":"key","in":"query","schema":{"type":"string"}},{"name":"locale","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"A page of templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `templates:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/otp/send":{"post":{"summary":"Issue a one-time code","description":"Scope `otp:send`. Sends a code through the messaging pipeline with tag `otp` (so a routing rule can prefer a fast route), using the environment's `otp` template when it has one. Length, TTL, attempts and resend cooldown default to the environment's settings (6 digits, 5 minutes, 3 attempts, 60 s). The code is never returned; keep `id` to verify.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendOtpRequest"}}}},"responses":{"202":{"description":"The challenge; the code is queued for delivery. On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpChallenge"}}}},"400":{"description":"Invalid body, or no Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Production and staging: the wallet can’t cover the code’s price (`insufficient_balance`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `otp:send`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The destination is suppressed (`suppressed_destination`), no routing rule matches (`no_route`), or the named template is missing or not approved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Inside the resend cooldown for this destination (`rate_limited`, with `Retry-After`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/otp/verify":{"post":{"summary":"Check a code","description":"Scope `otp:verify`. Every attempt answers 200 with a `result`: `verified` (emits `otp.verified`), `invalid_code` (attempts remain), `too_many_attempts`, `expired` (emits `otp.expired`) or `already_verified`. A challenge is bound to its destination, so a code sent to one number cannot verify another.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpRequest"}}}},"responses":{"200":{"description":"The result of this attempt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpResponse"}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `otp:verify`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such challenge in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/verifications":{"post":{"summary":"Start an identity check","description":"Scope `verifications:create`. `type` `nrc_lookup` matches an NRC number and name against the registry; `document` reads and checks an identity document; `liveness` checks a live person took 1 to 8 selfie frames (`pass`, `fail` or `inconclusive`, with a score); `face_match` compares a selfie with a reference photo (passing at 85% similarity unless the environment changes it). Images are base64, up to 5 MB each and 10 MB together, kept as encrypted evidence. `kyc_basic` runs the environment's steps in order (by default document, face match, liveness and NRC lookup; the business portal sets which, in what order, and which stop the flow when they fail) from one subject: the document (also the face match's reference), the selfie frames (the first is the face match's selfie), and `nrc`, or an NRC document's expected number and names. It gives one decision: any step failing fails it, a step that couldn't run leaves it `failed` (`step_failed`), any review is review. `steps` and its events carry every step, and each completed step is billed at its own type's rate. Answers 202 with `status: pending`; the result arrives as `verification.completed` (with `decision` `pass`, `review` or `fail` against the environment's thresholds) or `verification.failed`. `callback_url` must be one of the environment's webhook endpoints; its events go there too. Sandbox runs against the simulator: NRC and document numbers ending `/10/1` match, `/10/2` are not found (a tampered document), `/10/3` partially match, `/10/9` fail; selfies pass and match unless an image carries `switchgear-test:` with `liveness=fail`, `inconclusive` or `error`, or `face_match=no_match`, `borderline` or `error` (the SDK exports such images as `VERIFICATION_TEST_IMAGES`).","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVerificationRequest"}}}},"responses":{"202":{"description":"The pending verification On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"400":{"description":"Invalid body (including images over 10 MB together, or a kyc_basic without the NRC its NRC lookup needs), or no Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `verifications:create`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"No verification provider runs this type, or one of kyc_basic's steps, in the environment (`no_route`, with `type` and `flow`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Saved but not queued (`dependency_unavailable`): retry with the same Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"summary":"List verifications","description":"Scope `verifications:read`. Newest first; no evidence links (open one verification for those).","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["nrc_lookup","document","liveness","face_match"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","completed","failed"]}},{"name":"decision","in":"query","schema":{"type":"string","enum":["pass","review","fail"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"A page of verifications","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `verifications:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/verifications/liveness/challenge":{"post":{"summary":"Start an active liveness challenge","description":"Scope `verifications:create`. Returns a signed, single-use `challenge`, valid for 2 minutes, and 2 or 3 `steps` in a random order (`blink`, `turn_left`, `turn_right`, `smile`). The app asks the person to do each in turn, takes 2 to 5 frames during each, and sends them as a `liveness` check with `subject.challenge` and `subject.steps` (`action`, `frames`, `times_ms`). A challenge already used, expired, from another environment or with steps in another order is refused (400). Runs on providers that support active liveness (verify-local, and the simulator in sandbox).","responses":{"201":{"description":"The challenge","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LivenessChallenge"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `verifications:create`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/verifications/{id}":{"get":{"summary":"Get a verification","description":"Scope `verifications:read`. The result, decision and reasons, with signed evidence links valid for 5 minutes (each download is audited). The subject is shown masked. Evidence is deleted after 7 days in sandbox and staging, 90 in production; the decision stays. A kyc_basic flow returns its `steps` inline, each with its result and provider response. A step can also be read by its own id (from `steps` or the event), with `parent_id` naming its flow; lists show only the flow.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The verification","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `verifications:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such verification in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/push/apps":{"put":{"summary":"Register or update a push app","description":"Scope `push:manage`. One app on one route: an Android package (`fcm` or `hms`), an iOS bundle id (`apns`), or a web origin (`web`). For FCM and Huawei, pass the parsed `google-services.json` or `agconnect-services.json` as `config_file`: only identifiers are kept (never API keys or the Huawei client secret), and they are checked against the environment’s credentials (`push_config_mismatch` when the file is for another project). A web app gets the environment’s VAPID public key, made on first use.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutPushAppRequest"}}}},"responses":{"200":{"description":"The app and its check","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushApp"}}}},"400":{"description":"Invalid identifier or file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `push:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The file names another project or app than the credentials (`push_config_mismatch`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"summary":"List push apps","responses":{"200":{"description":"The environment’s push apps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushAppList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `push:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/push/devices":{"put":{"summary":"Register a push device","description":"Scope `push:devices`. Idempotent: the same address again refreshes it, and under another `user_id` moves it (a shared phone). Addresses: `fcm_fid` (preferred) or `fcm_token`, `hms_token`, `apns_token` (with `environment` from the app build), or a `webpush_subscription` on a known push service. Outside sandbox, `app_id` must be a registered app. Send with `POST /v1/messages` `{ channel: \"push\", to: \"user:<user_id>\" }`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterPushDeviceRequest"}}}},"responses":{"200":{"description":"The device (never its address)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushDevice"}}}},"400":{"description":"Invalid address or app id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `push:devices`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The app is not registered (`push_app_not_registered`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/push/devices/query":{"post":{"summary":"List push devices","description":"Scope `push:devices`. Filter by `user_id`; live devices only unless `include_invalidated`; cursor-paginated. A POST so the user id (often an email or phone number) stays out of URLs and logs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushDeviceQuery"}}}},"responses":{"200":{"description":"A page of devices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushDeviceList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `push:devices`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/push/devices/{id}":{"delete":{"summary":"Stop sending to a device (logout)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Invalidated"},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `push:devices`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No live device with this id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/suppressions":{"post":{"summary":"Suppress a destination","description":"Scope `suppressions:write`. Stop sending to a phone number, email address or push target, on one `channel` or (null or absent) on every channel. Sends to it then fail with 422 `suppressed_destination` until the suppression is removed. Idempotent without an Idempotency-Key: an active suppression for the same destination, channel and scope comes back as it is, with 200. `scope: bulk` (channel `email` only) stops just the emails that carry an unsubscribe link, for unsubscribes kept in your own systems; codes, receipts and `transactional` email still go. Opt-outs reported by Africa’s Talking, permanent email bounces and spam complaints reported by Resend, and unsubscribes from bulk email (scope `bulk`) are added automatically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSuppressionRequest"}}}},"responses":{"200":{"description":"Already suppressed: the existing suppression","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Suppression"}}}},"201":{"description":"Suppressed (never the destination itself: a masked form and a hint)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Suppression"}}}},"400":{"description":"Invalid destination for the channel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `suppressions:write`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/suppressions/query":{"post":{"summary":"List suppressions","description":"Scope `suppressions:write`. Active suppressions, newest first, cursor-paginated. Filter by an exact `destination`, by `channel` (its own and the all-channel ones) or by `source`. A POST so a destination stays out of URLs and logs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionQuery"}}}},"responses":{"200":{"description":"A page of suppressions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `suppressions:write`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/suppressions/{id}":{"delete":{"summary":"Remove a suppression","description":"Scope `suppressions:write`. Sends to the destination work again. The removal is kept on record with the key that made it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed"},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `suppressions:write`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No active suppression with this id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/sandbox/inbox/query":{"post":{"summary":"Read what the simulators delivered to a destination","description":"Sandbox keys only (scope `messages:read`), for automated tests: returns simulator deliveries to `to`, newest first, with the body as the handset got it, so a test can read an OTP code. Only the last 7 days are kept. A POST so the destination stays out of URLs and logs. Delivery is asynchronous: poll, or use `sandbox.waitForMessage` in the SDK.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInboxQuery"}}}},"responses":{"200":{"description":"Deliveries, newest first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInbox"}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:read` (`insufficient_scope`), or is not a sandbox key (`sandbox_only`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/sandbox/inbound":{"post":{"summary":"Simulate a person writing to the sandbox on WhatsApp","description":"Sandbox keys only (scope `messages:send`). The message arrives through the same path as Meta's webhook: it appears on `GET /v1/inbound`, emits `inbound.received`, and opens the 24-hour window for replies. `media` makes up a file of `size_bytes` and `mime_type` (default 2 KB of the kind's first type), which is downloaded and kept like a real one, or refused if it breaks WhatsApp's limits, so a test can try both.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInboundRequest"}}}},"responses":{"202":{"description":"Queued; find it by `provider_ref`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInboundResponse"}}}},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:send` (`insufficient_scope`), or is not a sandbox key (`sandbox_only`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Not queued (`dependency_unavailable`); retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/media":{"post":{"summary":"Upload a file to send on WhatsApp","description":"Scope `messages:send`. `multipart/form-data` with the file in `file`; `kind` (`image`, `document`, `audio`, `video`) defaults from its type, and `filename` (what a document's recipient sees) from the upload. Send it with `whatsapp.media.media_id`, or name it as a template header's sample. Limits are Meta's: image up to 5 MB (image/jpeg, image/png); document up to 16 MB (application/pdf, text/plain, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation); audio up to 16 MB (audio/aac, audio/amr, audio/mpeg, audio/mp4, audio/ogg); video up to 16 MB (video/mp4, video/3gpp). Kept encrypted for 7 days in sandbox and staging, 30 in production.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"},"kind":{"type":"string","enum":["image","document","audio","video"]},"filename":{"type":"string","maxLength":240}}}}}},"responses":{"201":{"description":"The stored file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaObject"}}}},"400":{"description":"No `file`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:send`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Over WhatsApp's limit for the kind (`payload_too_large`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"A type WhatsApp doesn't send as that kind (`unsupported_media_type`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/media/{id}/content":{"get":{"summary":"Download a file a person sent in","description":"The signed link `GET /v1/inbound` gives in `media.url`, valid for 5 minutes; no API key, so it can go straight to a browser or a download tool. Fetch the inbound message again for a new link. Files are kept 7 days in sandbox and staging, 90 in production, then `media.status` is `expired`.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"exp","in":"query","required":true,"schema":{"type":"string"}},{"name":"sig","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file, as an attachment, in its own type"},"404":{"description":"The link has expired or is wrong, or the file is gone","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/usage":{"get":{"summary":"Usage and charges for a month","description":"Scope `usage:read`. What the API key's environment used in one UTC month, per channel and provider: billable messages (USSD: sessions), units (SMS segments, emails…) and what they were charged, in minor units of the organisation's `currency`. Sandbox usage is charged at zero. Statements in the business portal cover the whole organisation.","parameters":[{"name":"period","in":"query","description":"`YYYY-MM`; defaults to the current UTC month","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"The month’s usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"400":{"description":"`period` is not `YYYY-MM`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `usage:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/packages":{"get":{"summary":"Prepaid packages and what they have left","description":"Scope `usage:read`. The organisation's running prepaid packages (bought in the business portal), soonest end first, and their units left added up: SMS segments to Zambian numbers, WhatsApp utility and authentication templates, and emails. Package units are used before the wallet; international SMS, WhatsApp marketing, push, USSD and verification are always charged from the wallet. Sandbox never uses packages.","responses":{"200":{"description":"Running packages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackageBalance"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `usage:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/inbound":{"get":{"summary":"List inbound messages (replies and MO traffic)","description":"Scope `inbound:read`. Newest first; pass `next_cursor` as `cursor` for older messages. `from` is masked (`+260*******01`); the full sender is never returned. `matched_message_id` is the message a reply answers, when the vendor says which (WhatsApp). Each new message also emits `inbound.received`. A WhatsApp file comes as `media`: `pending` while it downloads, then `stored` with a signed `url` valid for 5 minutes, or `too_large`, `unsupported` or `failed`. Reply within the window with `POST /v1/inbound/{id}/reply`.","parameters":[{"name":"channel","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"A page of inbound messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `inbound:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/inbound/{id}":{"get":{"summary":"One inbound message","description":"Scope `inbound:read`. For example the `inbound_id` of an `inbound.received` event, which carries no text.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundMessage"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `inbound:read`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such inbound message in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/inbound/{id}/reply":{"post":{"summary":"Reply on WhatsApp inside the customer-service window","description":"Scope `messages:send`. Free text (`body`) or a file (`media`, with `body` as its caption) back to the person who sent this message, quoting it. Meta allows it only within 24 hours of the person's last message; after that, send an approved template with `POST /v1/messages`. Billed as a WhatsApp service conversation. The answer is the queued message; follow it like any other.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundReplyRequest"}}}},"responses":{"202":{"description":"The queued reply. On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Invalid body, a message on another channel, or no Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"The wallet can’t cover the estimated price (`insufficient_balance`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `messages:send`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such inbound message in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"The uploaded file is not a type WhatsApp sends as that kind (`unsupported_media_type`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"More than 24 hours since the person last wrote (`outside_service_window`, with `last_inbound_at`), or an unknown or expired `media_id` (`media_not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/ussd/sessions/{id}/end":{"post":{"summary":"End a live USSD session","description":"Scope `ussd:manage`. Closes the session now and emits `ussd.session.ended` with reason `api_end`. The handset still shows the last screen; the next request the telco makes gets `text` (default \"This session has ended.\") as a closing screen. The id is the `session_id` your callback receives. Each step of a session is a signed POST to the shortcode's callback (`UssdCallbackRequest`), answered with `UssdCallbackResponse` within the shortcode's budget.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndUssdSessionRequest"}}}},"responses":{"200":{"description":"Ended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndUssdSessionResponse"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `ussd:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No live session with that id in this environment (sessions live in the gateway only while active)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The session has already ended (`ussd_session_ended`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/ussd/emulator":{"post":{"summary":"Drive a USSD session on the simulator (sandbox)","description":"Scope `ussd:manage`, sandbox keys only. Start with `dial` (a simulator shortcode of this environment, optionally with extra digits: `*384*55*1#`), then send `session` with each `input`. Runs the same session engine and calls the same callback as a telco would. Digits after the code are step 0 `input`, as from a telco: `*388*4*334466*20#` on `*388*4#` gives `334466*20`. `msisdn` (E.164 with the plus, default `+260970000001`) and `network` (MCC-MNC such as `64502`; default null) go with `dial` and reach the callback on every step. The answer is `{ session, msisdn, text, end }`, not the callback's `{ text, action, state }`: `end` is true once the session is over.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UssdEmulatorRequest"}}}},"responses":{"200":{"description":"The screen to show","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UssdEmulatorResponse"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `ussd:manage` (`insufficient_scope`), or is not a sandbox key (`sandbox_only`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No simulator shortcode matches the dial, or the session handle is unknown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The emulator session has ended; dial again","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints":{"post":{"summary":"Register a webhook endpoint","description":"Scope `webhooks:manage`. Returns the signing secret once (a replay within 24 hours repeats it). `event_types` empty means every type. Outside sandbox the URL must be https. See the `webhooks` section for the events and their signature.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request, for example a UUID. A retry with the same key and body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"}}}},"responses":{"201":{"description":"The endpoint with its secret. On a replay the response carries `Idempotent-Replayed: true`.","headers":{"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedWebhookEndpoint"}}}},"400":{"description":"Invalid body or URL, or no Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `webhooks:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The Idempotency-Key was used with a different body, or more than 24 hours ago","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"summary":"List webhook endpoints (without secrets)","responses":{"200":{"description":"The environment's endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `webhooks:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints/{id}":{"delete":{"summary":"Turn a webhook endpoint off","description":"Scope `webhooks:manage`. The endpoint stops receiving events at once (deliveries already queued for it are dropped) and stays in the list with `enabled: false`, with its delivery history. Turn it back on in the business portal. Doing it again changes nothing.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Off"},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key lacks `webhooks:manage`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No webhook endpoint with this id in this environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"webhooks":{"message.queued":{"post":{"summary":"message.queued event","description":"POSTed to every enabled endpoint that takes `message.queued`. `data` is a MessageEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["message.queued"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"message.sent":{"post":{"summary":"message.sent event","description":"POSTed to every enabled endpoint that takes `message.sent`. `data` is a MessageEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["message.sent"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"message.delivered":{"post":{"summary":"message.delivered event","description":"POSTed to every enabled endpoint that takes `message.delivered`. `data` is a MessageEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["message.delivered"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"message.failed":{"post":{"summary":"message.failed event","description":"POSTed to every enabled endpoint that takes `message.failed`. `data` is a MessageEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["message.failed"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"inbound.received":{"post":{"summary":"inbound.received event","description":"POSTed to every enabled endpoint that takes `inbound.received`. `data` is a InboundEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["inbound.received"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"otp.verified":{"post":{"summary":"otp.verified event","description":"POSTed to every enabled endpoint that takes `otp.verified`. `data` is a OtpEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["otp.verified"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"otp.expired":{"post":{"summary":"otp.expired event","description":"POSTed to every enabled endpoint that takes `otp.expired`. `data` is a OtpEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["otp.expired"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"verification.completed":{"post":{"summary":"verification.completed event","description":"POSTed to every enabled endpoint that takes `verification.completed`. `data` is a VerificationEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["verification.completed"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"verification.failed":{"post":{"summary":"verification.failed event","description":"POSTed to every enabled endpoint that takes `verification.failed`. `data` is a VerificationEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["verification.failed"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ussd.session.started":{"post":{"summary":"ussd.session.started event","description":"POSTed to every enabled endpoint that takes `ussd.session.started`. `data` is a UssdSessionStartedData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["ussd.session.started"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ussd.session.ended":{"post":{"summary":"ussd.session.ended event","description":"POSTed to every enabled endpoint that takes `ussd.session.ended`. `data` is a UssdSessionEndedData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["ussd.session.ended"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ussd.screen.truncated":{"post":{"summary":"ussd.screen.truncated event","description":"POSTed to every enabled endpoint that takes `ussd.screen.truncated`. `data` is a UssdScreenTruncatedData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["ussd.screen.truncated"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"email.unsubscribed":{"post":{"summary":"email.unsubscribed event","description":"POSTed to every enabled endpoint that takes `email.unsubscribed`. `data` is a EmailUnsubscribedEventData. Verify `X-Switchgear-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret, for example with `verifyWebhook` from `@brivo/switchgear`) and reject anything older than 5 minutes. Delivery is at least once: deduplicate on `id` (also in `X-Switchgear-Event-Id`). Anything but a 2xx within 10 s is retried with exponential backoff from 30 s for 24 hours.","parameters":[{"name":"X-Switchgear-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Switchgear-Event-Id","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Switchgear-Event-Type","in":"header","required":true,"schema":{"type":"string","enum":["email.unsubscribed"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}}}}