{"info":{"_postman_id":"892f8fc3-7c71-4bd3-862f-a425de09cb77","name":"Relay360","description":"<html><head></head><body><h2 id=\"introduction\">Introduction</h2>\n<p>Welcome to the <strong>Relay360 API Documentation</strong> — your gateway to building reliable, high-volume communication workflows for <strong>notifications, alerts, and multi-channel campaigns</strong> across SMS, Voice, WhatsApp, and Email. Relay360 provides a unified job-processing and verification engine designed for scale, speed, and operational clarity.</p>\n<p>Before you begin, make sure the following are in place:</p>\n<ol>\n<li><p><strong>Create a developer account</strong> on the <a href=\"https://relay360.dev\">Relay360</a> platform.</p>\n</li>\n<li><p><strong>Retrieve your API key</strong> from your <a href=\"https://relay360.dev\">Relay360</a> dashboard.</p>\n</li>\n<li><p><strong>Fund your account</strong> with sufficient messaging and voice credits.</p>\n</li>\n</ol>\n<p>With your setup complete, the sections ahead will walk you through authentication, request formats, channel guides, and best practices for orchestrating dependable, high-throughput communication workflows.</p>\n<hr>\n<h2 id=\"authentication\">Authentication</h2>\n<p>Relay360 uses standard <strong>Bearer Token</strong> authentication for all API requests.</p>\n<p>Include the <strong>Authorization</strong> header with every request you send. This header identifies your application and allows the platform to validate the request source.</p>\n<p><strong>Format:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer &lt;YOUR_API_KEY&gt;\n\n</code></pre><h2 id=\"content-types\">Content Types</h2>\n<p>Relay360 accepts two primary content types:</p>\n<ul>\n<li><p><strong><code>application/json</code></strong> — for standard requests that do not include file uploads</p>\n</li>\n<li><p><strong><code>multipart/form-data</code></strong> — for requests that involve file uploads</p>\n</li>\n</ul>\n<p>Always set the appropriate <code>Content-Type</code> header based on the nature of your request.</p>\n<h2 id=\"base-url\">Base URL</h2>\n<p>The Relay360 production base url is <code>https://api.relay360.dev/v1</code></p>\n<hr>\n<p>All set? Explore the available endpoints below and start integrating Relay360 into your notification and campaign workflows.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"2241118","collectionId":"892f8fc3-7c71-4bd3-862f-a425de09cb77","publishedId":"2sB3dLTrgy","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"9333ea"},"publishDate":"2025-12-02T00:26:59.000Z"},"item":[{"name":"Message Dispatch","item":[{"name":"Create SMS Dispatch Job","id":"ccc504d6-60a1-4a47-bdd8-c4ea39d6cc8c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdns\": \"+2348124163122\",\n\"name\": \"test\",\n\"message_text\": \"Hello to you too\",\n\"external_id\": \"91b49feb-4642-5b6b-911f-4c874e202d8b\",\n\"webhook_url\": \"https://webhook.site/a27c8be1-2b90-48cc-b28e-8e4da0b2b288\"\n}"},"url":"{{BASE_URL}}/dispatch/sms","description":"<p>This endpoint allows you to instantly send or schedule an SMS message to one or more phone numbers, or to a phonebook you’ve created on your Relay360 dashboard. All phone numbers must include the appropriate international dialing code.</p>\n<p>If you’ve registered a custom sender ID on Relay360, you can include it in your request body so that recipients receive the SMS using your approved sender identity.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer API_KEY</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>json body</td>\n<td>A descriptive name for the SMS dispatch job.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>msisdns</td>\n<td>json body</td>\n<td>List of phone numbers (in full international format) to send the SMS to.</td>\n<td>No</td>\n<td>array of strings</td>\n</tr>\n<tr>\n<td>phonebook_id</td>\n<td>json body</td>\n<td>ID of a phonebook on your Relay360 account. Use this OR msisdns.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>message_text</td>\n<td>json body</td>\n<td>The SMS message body.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>run_time</td>\n<td>json body</td>\n<td>Optional datetime (e.g., <code>2025-12-25 12:40:12</code>). If omitted, the message is sent immediately.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>sender_id</td>\n<td>json body</td>\n<td>Optional custom sender ID registered and approved on your Relay360 dashboard. Only works for local numbers.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n","urlObject":{"path":["dispatch","sms"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"ccc504d6-60a1-4a47-bdd8-c4ea39d6cc8c"},{"name":"Create WhatsApp Dispatch Job","id":"c910a2fa-b3d3-4ca5-8357-288987c6e548","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"name\": \"test mic 12345\",\n\"template\": \"hello_world\",\n\"msisdns\": \"+2348124163122\"\n}"},"url":"{{BASE_URL}}/dispatch/whatsapp","description":"<p>This endpoint allows you to instantly send a WhatsApp message to one or more phone numbers, or to a phonebook you've created on your Relay360 dashboard. All phone numbers must be in full international format.</p>\n<p>WhatsApp requires all outbound messages to use an approved template. Once you've created and registered a template on Relay360 and it has been approved, you may reference it in your request using the <code>template</code> parameter.</p>\n<h4 id=\"template-features-support\">Template Features Support</h4>\n<p><strong>1. Template Variables</strong></p>\n<ul>\n<li>WhatsApp templates can include dynamic variables (<code>{{1}}</code>, <code>{{2}}</code>, etc.)</li>\n<li>Use the <code>variables</code> parameter to supply values in the correct order</li>\n<li>Maximum 10 variables per template</li>\n</ul>\n<p><strong>2. Header Media Support</strong> You can attach media to your WhatsApp template header:</p>\n<ul>\n<li><strong>Image</strong>: Use <code>image_url</code> parameter (JPG, PNG, GIF)</li>\n<li><strong>Video</strong>: Use <code>video_url</code> parameter (MP4, 3GPP)</li>\n<li><strong>Document</strong>: Use <code>document_url</code> parameter (PDF, DOC, etc.)</li>\n</ul>\n<p><strong>Important Notes:</strong></p>\n<ul>\n<li>Only ONE header type per message (image, video, OR document)</li>\n<li>If multiple URLs are provided, priority: <code>video_url</code> &gt; <code>document_url</code> &gt; <code>image_url</code></li>\n<li>All media URLs must be publicly accessible</li>\n<li>Do not send more than 1,000 numbers per request</li>\n</ul>\n<hr />\n<h3 id=\"http-request\">HTTP Request</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST https://api.relay360.dev/v1/dispatch/whatsapp\n\n</code></pre><h3 id=\"header-parameters\">Header Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td>Bearer {your_api_key}</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td>application/json</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"body-parameters\">Body Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>body</td>\n<td>Name to identify the WhatsApp dispatch job</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>msisdns</td>\n<td>body</td>\n<td>Comma-separated list of phone numbers (full international format)</td>\n<td>No*</td>\n<td>string</td>\n</tr>\n<tr>\n<td>phonebook_id</td>\n<td>body</td>\n<td>ID of a phonebook on your Relay360 account</td>\n<td>No*</td>\n<td>string</td>\n</tr>\n<tr>\n<td>template</td>\n<td>body</td>\n<td>Name of an approved WhatsApp template</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>variables</td>\n<td>body</td>\n<td>Array of values replacing template variables (<code>{{1}}</code>, <code>{{2}}</code>, etc.)</td>\n<td>No</td>\n<td>array</td>\n</tr>\n<tr>\n<td>image_url</td>\n<td>body</td>\n<td>URL of an image (JPG, PNG, GIF) for header</td>\n<td>No</td>\n<td>string (URL)</td>\n</tr>\n<tr>\n<td>video_url</td>\n<td>body</td>\n<td>URL of a video (MP4, 3GPP) for header</td>\n<td>No</td>\n<td>string (URL)</td>\n</tr>\n<tr>\n<td>document_url</td>\n<td>body</td>\n<td>URL of a document (PDF, DOC, etc.) for header</td>\n<td>No</td>\n<td>string (URL)</td>\n</tr>\n<tr>\n<td>run_time</td>\n<td>body</td>\n<td>Schedule message for future delivery (ISO 8601 format)</td>\n<td>No</td>\n<td>string (datetime)</td>\n</tr>\n</tbody>\n</table>\n</div><p>*Either <code>msisdns</code> OR <code>phonebook_id</code> is required</p>\n<hr />\n<h3 id=\"creating-templates-with-variables-and-headers\">Creating Templates with Variables and Headers</h3>\n<h4 id=\"step-1-log-in-to-relay360-dashboard\">Step 1: Log in to Relay360 Dashboard</h4>\n<ol>\n<li>Go to <strong>WhatsApp Templates</strong></li>\n<li>Click <strong>Create New Template</strong></li>\n</ol>\n<h4 id=\"step-2-configure-template\">Step 2: Configure Template</h4>\n<p><strong>Example 1: Template with Variables + Image Header</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Template Name: product_announcement\nCategory: MARKETING\nHeader Type: Image\nMessage Body: Hello {{1}}! Check out our new {{2}} for only {{3}}. Limited time offer!\n\n</code></pre><p><strong>Example 2: Template with Variables + Video Header</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Template Name: tutorial_video\nCategory: UTILITY\nHeader Type: Video\nMessage Body: Hi {{1}}, here's the tutorial you requested for {{2}}.\n\n</code></pre><p><strong>Example 3: Template with Variables + Document Header</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Template Name: invoice_delivery\nCategory: UTILITY\nHeader Type: Document\nMessage Body: Dear {{1}}, your invoice #{{2}} for {{3}} is attached above.\n\n</code></pre><p><strong>Example 4: Template with Variables Only (No Header)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Template Name: welcome_message\nCategory: MARKETING\nHeader Type: None\nMessage Body: Hello {{1}}! Welcome to {{2}}. Your subscription expires on {{3}}.\n\n</code></pre><h4 id=\"step-3-submit-for-approval\">Step 3: Submit for Approval</h4>\n<ul>\n<li>All templates require Meta/WhatsApp approval before use</li>\n<li>Approval usually takes 1-24 hours</li>\n<li>You'll receive an email notification when approved/rejected</li>\n</ul>\n<hr />\n<h3 id=\"api-usage-examples\">API Usage Examples</h3>\n<h4 id=\"example-1-message-with-variables-and-image-header\">Example 1: Message with Variables and Image Header</h4>\n<p><strong>Request:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">POST https://api.relay360.dev/v1/dispatch/whatsapp\nAuthorization: Bearer YOUR_API_KEY\nContent-Type: application/json\n{\n  \"name\": \"Product Launch Campaign\",\n  \"msisdns\": \"+2348012345678,+2348087654321\",\n  \"template\": \"product_announcement\",\n  \"variables\": [\"John Doe\", \"Smart Phone X\", \"₦150,000\"],\n  \"image_url\": \"https://example.com/images/smartphone.jpg\"\n}\n\n</code></pre>\n<p><strong>Response:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": true,\n  \"message\": \"WhatsApp broadcast sent\",\n  \"data\": {\n    \"id\": 12345,\n    \"name\": \"Product Launch Campaign\",\n    \"client_id\": 100,\n    \"type\": \"whatsapp\",\n    \"status\": \"success\",\n    \"created_at\": \"2025-12-13T10:30:00Z\"\n  }\n}\n\n</code></pre>\n<hr />\n<h4 id=\"example-2-message-with-variables-and-video-header\">Example 2: Message with Variables and Video Header</h4>\n<p><strong>Request:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Tutorial Distribution\",\n  \"phonebook_id\": \"567\",\n  \"template\": \"tutorial_video\",\n  \"variables\": [\"Sarah\", \"Advanced Features\"],\n  \"video_url\": \"https://example.com/videos/tutorial.mp4\"\n}\n\n</code></pre>\n<hr />\n<h4 id=\"example-3-message-with-variables-and-document-header\">Example 3: Message with Variables and Document Header</h4>\n<p><strong>Request:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Invoice Delivery\",\n  \"msisdns\": \"+2348012345678\",\n  \"template\": \"invoice_delivery\",\n  \"variables\": [\"John Smith\", \"INV-2025-001\", \"December 2025\"],\n  \"document_url\": \"https://example.com/invoices/INV-2025-001.pdf\"\n}\n\n</code></pre>\n<hr />\n<h4 id=\"example-4-message-with-variables-only-no-header-media\">Example 4: Message with Variables Only (No Header Media)</h4>\n<p><strong>Request:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Welcome Campaign\",\n  \"msisdns\": \"+2348012345678,+2348087654321\",\n  \"template\": \"welcome_message\",\n  \"variables\": [\"John Doe\", \"Premium Service\", \"December 31, 2025\"]\n}\n\n</code></pre>\n<hr />\n<h4 id=\"example-5-scheduled-message\">Example 5: Scheduled Message</h4>\n<p><strong>Request:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Reminder Campaign\",\n  \"phonebook_id\": \"789\",\n  \"template\": \"appointment_reminder\",\n  \"variables\": [\"Sarah\", \"December 15, 2025\", \"2:00 PM\"],\n  \"run_time\": \"2025-12-14T08:00:00Z\"\n}\n\n</code></pre>\n<hr />\n<h3 id=\"variable-replacement-rules\">Variable Replacement Rules</h3>\n<p>Variables are replaced in sequential order:</p>\n<ul>\n<li>First array element → <code>{{1}}</code></li>\n<li>Second element → <code>{{2}}</code></li>\n<li>Third element → <code>{{3}}</code></li>\n<li>And so on...</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"template\": \"order_update\",\n  \"variables\": [\"John\", \"ORD123\", \"Shipped\", \"Dec 15\"]\n}\n\n</code></pre>\n<p>For template: <code>\"Hello {{1}}, order {{2}} is {{3}}. Expected delivery: {{4}}\"</code></p>\n<p>Result: <code>\"Hello John, order ORD123 is Shipped. Expected delivery: Dec 15\"</code></p>\n<hr />\n<h3 id=\"header-media-priority\">Header Media Priority</h3>\n<p>If you provide multiple header URLs, the service will use them in this priority order:</p>\n<ol>\n<li><strong>video_url</strong> (highest priority)</li>\n<li><strong>document_url</strong> (medium priority)</li>\n<li><strong>image_url</strong> (lowest priority)</li>\n</ol>\n<p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"template\": \"product_promo\",\n  \"image_url\": \"https://example.com/image.jpg\",\n  \"video_url\": \"https://example.com/video.mp4\"\n}\n\n</code></pre>\n<p>Result: Only the video will be used (video_url takes priority)</p>\n<hr />\n<h3 id=\"error-responses\">Error Responses</h3>\n<h4 id=\"template-not-found-or-unapproved\">Template Not Found or Unapproved</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": false,\n  \"error\": \"Template invalid or unapproved\"\n}\n\n</code></pre>\n<h4 id=\"insufficient-balance\">Insufficient Balance</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": false,\n  \"error\": \"Insufficient balance. Please load some airtime credit.\"\n}\n\n</code></pre>\n<h4 id=\"variable-count-mismatch\">Variable Count Mismatch</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": false,\n  \"error\": \"Template requires 3 variables but 2 were provided\"\n}\n\n</code></pre>\n<h4 id=\"invalid-media-url\">Invalid Media URL</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": false,\n  \"error\": {\n    \"image_url\": [\"The image url format is invalid.\"]\n  }\n}\n\n</code></pre>\n<hr />\n<h3 id=\"best-practices\">Best Practices</h3>\n<ol>\n<li><strong>Always Test First</strong>: Test templates with a small audience before full deployment</li>\n<li><strong>Variable Content</strong>: Ensure variable values are appropriate and relevant</li>\n<li><strong>Media Quality</strong>: Use high-quality, properly formatted media files</li>\n<li><strong>URL Accessibility</strong>: Verify all media URLs are publicly accessible</li>\n<li><strong>Batch Size</strong>: Keep batches under 1,000 recipients for optimal performance</li>\n<li><strong>Personalization</strong>: Use variables to personalize messages for better engagement</li>\n<li><strong>Template Categories</strong>:<ul>\n<li><strong>MARKETING</strong>: Promotional content, offers, announcements</li>\n<li><strong>UTILITY</strong>: Account updates, alerts, reminders</li>\n<li><strong>AUTHENTICATION</strong>: OTPs, verification codes</li>\n</ul>\n</li>\n</ol>\n","urlObject":{"path":["dispatch","whatsapp"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"1575b145-2a52-45fc-9a6c-873ffd22fead","name":"Create WhatsApp Dispatch Job","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"name\": \"test mic 12345\",\n\"template\": \"hello_world\",\n\"msisdns\": \"+2348124163122\"\n}"},"url":"{{BASE_URL}}/dispatch/whatsapp"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 01:28:27 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"597"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"message\": \"WhatsApp broadcast sent\",\n    \"data\": {\n        \"name\": \"test mic 12345\",\n        \"client_id\": 38,\n        \"type\": \"whatsapp\",\n        \"whatsapp_template\": \"hello_world\",\n        \"sender_id\": null,\n        \"run_time\": \"2025-11-29T01:28:24.374226Z\",\n        \"updated_at\": \"2025-11-29T01:28:27.000000Z\",\n        \"created_at\": \"2025-11-29T01:28:24.000000Z\",\n        \"id\": 181,\n        \"status\": \"success\",\n        \"reciepentsno\": 1,\n        \"cost\": \"calculated\"\n    }\n}"}],"_postman_id":"c910a2fa-b3d3-4ca5-8357-288987c6e548"},{"name":"Create Email Dispatch Job","id":"dde15a74-f136-459b-8d84-089e22ee8068","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Promo Email - November\",\n  \"emails\": \"josholatunde@gmail.com\",\n  \"from_email\": \"noreply@lafira.pro\",\n  \"from_name\": \"Lafira\",\n  \"subject\": \"Welcome to our January Promo!\",\n  \"message_text\": \"Hello! Check out our latest January offers.\",\n  \"message_html\": \"<h1>January Promo</h1><p>Hello! Check out our latest January offers.</p>\"\n}"},"url":"{{BASE_URL}}/dispatch/email","description":"<p>This endpoint allows you to send emails to one or more recipients using Relay360. Before sending emails, ensure you have <strong>added and verified a sending domain</strong> on your Relay360 dashboard. Verified senders guarantee deliverability and compliance with email standards.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td>Enter your generated API key</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>json body</td>\n<td>A unique name identifying the email job</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>emails</td>\n<td>json body</td>\n<td>A comma-separated list of email addresses</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>from_email</td>\n<td>json body</td>\n<td>The \"from\" email address. Domain must be verified. e.g <a href=\"https://mailto:no-reply@verified.domain\">no-reply@verified.domain</a></td>\n<td>Yes</td>\n<td>email</td>\n</tr>\n<tr>\n<td>from_name</td>\n<td>json body</td>\n<td>Display name for the sender</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>subject</td>\n<td>json body</td>\n<td>Subject line of the email</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>message_text</td>\n<td>json body</td>\n<td>Plain-text version of the email content</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>message_html</td>\n<td>json body</td>\n<td>HTML version of the email content</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>run_time</td>\n<td>json body</td>\n<td>Optional scheduled sending time (must be a future datetime)</td>\n<td>No</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\"><strong>Notes</strong></h3>\n<ul>\n<li>At least <strong>one</strong> of <code>message_text</code> or <code>message_html</code> should be included.</li>\n<li><code>emails</code> must be a comma-separated string (e.g. <code>\"john@example.com,jane@example.com\"</code>).</li>\n<li>When <code>run_time</code> is omitted, the email is dispatched immediately.</li>\n<li>Emails are sent <strong>only</strong> through verified domains.</li>\n</ul>\n","urlObject":{"path":["dispatch","email"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"830e6881-e66b-4c6a-8046-fae9d2d8e89a","name":"Create Email Dispatch Job - Instant","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Promo Email - November\",\n  \"emails\": \"josholatunde@gmail.com\",\n  \"from_email\": \"noreply@lafira.pro\",\n  \"from_name\": \"Lafira\",\n  \"subject\": \"Welcome to our January Promo!\",\n  \"message_text\": \"Hello! Check out our latest January offers.\",\n  \"message_html\": \"<h1>January Promo</h1><p>Hello! Check out our latest January offers.</p>\"\n}"},"url":"{{BASE_URL}}/dispatch/email"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 00:39:24 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"598"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"message\": \"Email broadcast sent successfully\",\n    \"data\": {\n        \"name\": \"Promo Email - November\",\n        \"client_id\": 38,\n        \"emails\": \"josholatunde@gmail.com\",\n        \"from_email\": \"noreply@lafira.pro\",\n        \"from_name\": \"Lafira\",\n        \"subject\": \"Welcome to our January Promo!\",\n        \"message_text\": \"Hello! Check out our latest January offers.\",\n        \"message_html\": \"<h1>January Promo</h1><p>Hello! Check out our latest January offers.</p>\",\n        \"status\": \"completed\",\n        \"total_recipients\": 1,\n        \"run_time\": \"2025-11-29T00:39:22.000000Z\",\n        \"updated_at\": \"2025-11-29T00:39:24.000000Z\",\n        \"created_at\": \"2025-11-29T00:39:22.000000Z\",\n        \"id\": 17,\n        \"sent_count\": 1\n    }\n}"},{"id":"edd9a3af-b294-4094-81ee-06fe64306f2b","name":"Create Email Dispatch Job - Schedule","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Promo Email - November\",\n  \"emails\": \"josholatunde@gmail.com\",\n  \"from_email\": \"noreply@lafira.pro\",\n  \"from_name\": \"Lafira\",\n  \"subject\": \"Welcome to our January Promo!\",\n  \"message_text\": \"Hello! Check out our latest January offers.\",\n  \"message_html\": \"<h1>January Promo</h1><p>Hello! Check out our latest January offers.</p>\",\n  \"run_time\": \"2025-11-29 01:55:00\"\n}"},"url":"{{BASE_URL}}/dispatch/email"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 00:48:39 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"message\": \"Email broadcast scheduled successfully\",\n    \"data\": {\n        \"name\": \"Promo Email - November\",\n        \"client_id\": 38,\n        \"emails\": \"josholatunde@gmail.com\",\n        \"from_email\": \"noreply@lafira.pro\",\n        \"from_name\": \"Lafira\",\n        \"subject\": \"Welcome to our January Promo!\",\n        \"message_text\": \"Hello! Check out our latest January offers.\",\n        \"message_html\": \"<h1>January Promo</h1><p>Hello! Check out our latest January offers.</p>\",\n        \"status\": \"completed\",\n        \"total_recipients\": 1,\n        \"run_time\": \"2025-11-29T00:55:00.000000Z\",\n        \"updated_at\": \"2025-11-29T00:48:39.000000Z\",\n        \"created_at\": \"2025-11-29T00:48:37.000000Z\",\n        \"id\": 21,\n        \"sent_count\": 1\n    }\n}"}],"_postman_id":"dde15a74-f136-459b-8d84-089e22ee8068"},{"name":"Create Voice Dispatch Job","id":"8f2e53e7-ca05-468c-b919-0229f5b11e38","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdns\": \"+2348124163122\",\n\"name\": \"test\",\n\"message_text\": \"Hello to you too\",\n\"external_id\": \"91b49feb-4642-5b6b-911f-4c874e202d8b\",\n\"webhook_url\": \"https://webhook.site/a27c8be1-2b90-48cc-b28e-8e4da0b2b288\"\n}"},"url":"{{BASE_URL}}/dispatch/voice","description":"<p>This endpoint allows you to instantly send or schedule an outbound voice message to one or more phone numbers, or to a phonebook you’ve created on your Relay360 dashboard. All phone numbers must include the full international dialing code.</p>\n<p>If you have one or more verified outbound phone numbers on Relay360, you may specify one using the <code>phone_number</code> parameter so recipients see that number as the caller ID.</p>\n<p>Voice messages can be delivered in two ways:</p>\n<ul>\n<li><p>By uploading an <strong>audio file</strong> (<code>wav</code> or <code>mp3</code>)</p>\n</li>\n<li><p>By sending <strong>text</strong>, which Relay360 will automatically convert to audio</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>multipart/form-data</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters-form-data\"><strong>Body Parameters (form-data)</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>formData</td>\n<td>A descriptive name for the voice dispatch job.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>msisdns</td>\n<td>formData</td>\n<td>A comma-separated list of phone numbers (in full international format).</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>phonebook_id</td>\n<td>formData</td>\n<td>ID of a phonebook on your Relay360 account. Can be used instead of msisdns.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>message_audio</td>\n<td>formData</td>\n<td>Audio file (<code>wav</code> or <code>mp3</code>) containing the voice message.</td>\n<td>No</td>\n<td>file</td>\n</tr>\n<tr>\n<td>message_text</td>\n<td>formData</td>\n<td>Text to be converted to audio if no file is provided.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>webhook_url</td>\n<td>formData</td>\n<td>URL to receive delivery or status callbacks for this job.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>run_time</td>\n<td>formData</td>\n<td>Optional datetime (e.g., <code>2025-12-25 12:40:12</code>). If omitted, the job is processed immediately.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>external_id</td>\n<td>formData</td>\n<td>An optional identifier from your system to associate with the job. Must be ≤144 characters.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>phone_number</td>\n<td>formData</td>\n<td>A verified outbound phone number from your Relay360 account. Recipients will see this number as caller ID when specified.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["dispatch","voice"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"8f2e53e7-ca05-468c-b919-0229f5b11e38"},{"name":"Get analytics for a single dispatch job","id":"4acda824-c71e-4098-96c2-b8367ccc0406","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/dispatch/analytics/:id","description":"<p>This endpoint allows you to retrieve key analytics for a specific dispatch job.<br />You must provide the <strong>id</strong> returned when the job was initially created or scheduled.<br />You can also obtain this <strong>id</strong> by calling the <strong>Get All Dispatch Jobs</strong> endpoint.</p>\n<hr />\n<h3 id=\"response-guide\"><strong>Response Guide</strong></h3>\n<ul>\n<li><p><strong>totalProcessed</strong> — Total number of recipients associated with the dispatch job.</p>\n</li>\n<li><p><strong>success</strong> — Number of messages delivered successfully, or number of calls placed successfully (for voice dispatch jobs).</p>\n</li>\n<li><p><strong>pending</strong> — Number of messages not yet delivered, or calls not yet attempted or completed (for voice dispatch jobs).</p>\n</li>\n<li><p><strong>successRatePercentage</strong> — Percentage of successful deliveries, or call pickup rate (for voice dispatch jobs).</p>\n</li>\n</ul>\n","urlObject":{"path":["dispatch","analytics",":id"],"host":["{{BASE_URL}}"],"query":[],"variable":[{"type":"any","value":"3093","key":"id"}]}},"response":[{"id":"d8a55b6e-8056-45e3-8e02-1e3cfe7d2f10","name":"Get analytics for a single dispatch job","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":{"raw":"{{BASE_URL}}/dispatch/analytics/:id","host":["{{BASE_URL}}"],"path":["dispatch","analytics",":id"],"variable":[{"key":"id","value":"181"}]}},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 01:29:07 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"message\": \"Success\",\n    \"data\": {\n        \"totalProcessed\": 1,\n        \"success\": 0,\n        \"pending\": 1,\n        \"successRatePercentage\": \"0.00\",\n        \"job\": {\n            \"id\": 181,\n            \"name\": \"test mic 12345\",\n            \"client_id\": 38,\n            \"message_audio\": null,\n            \"message_text\": null,\n            \"run_time\": \"2025-11-29 02:28:24\",\n            \"status\": \"success\",\n            \"deleted_at\": null,\n            \"created_at\": \"2025-11-29T01:28:24.000000Z\",\n            \"updated_at\": \"2025-11-29T01:28:27.000000Z\",\n            \"type\": \"whatsapp\",\n            \"sender_id\": null,\n            \"webhook_url\": null,\n            \"whatsapp_template\": \"hello_world\",\n            \"external_id\": null,\n            \"expiry_time\": null,\n            \"phone_number\": null,\n            \"calculatedCost\": \"calculated\",\n            \"reciepentsno\": 1,\n            \"cost\": \"calculated\"\n        }\n    }\n}"}],"_postman_id":"4acda824-c71e-4098-96c2-b8367ccc0406"}],"id":"8a7ef7af-5235-4ca3-9c0f-3d1a3c89fa16","description":"<p>The Message Dispatch APIs allow you to send SMS, Voice, Email, or WhatsApp messages to one or multiple recipients. They also provide endpoints for checking the delivery status of any message across supported channels, giving you full visibility into each communication attempt.</p>\n","_postman_id":"8a7ef7af-5235-4ca3-9c0f-3d1a3c89fa16"},{"name":"Verification","item":[{"name":"Initiate SMS Verification Code","id":"9fefcf17-7781-4ded-a0ad-5be3dc6be8f3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdn\": \"+2348124163122\",\n\"otp\": \"1012JK\"\n}"},"url":"{{BASE_URL}}/verification/sms","description":"<p>This endpoint allows you to send a <strong>one-time verification code</strong> via SMS to a phone number.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>msisdn</td>\n<td>json body</td>\n<td>The recipient’s phone number in full international format.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>otp</td>\n<td>json body</td>\n<td>Optional. Specify the OTP to send. If not provided, Relay360 will generate one automatically.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>length</td>\n<td>json body</td>\n<td>Optional. Length of the OTP (only used if <code>otp</code> is not provided). Must be 4, 5, 6, 7, or 8.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>expires</td>\n<td>json body</td>\n<td>Optional. Time in minutes before the OTP expires. Default is 10 minutes.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>alphanumeric</td>\n<td>json body</td>\n<td>Optional. Set to <code>true</code> if the OTP should include letters. Only valid if <code>otp</code> is not provided. Defaults to <code>false</code>.</td>\n<td>No</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>message</td>\n<td>json body</td>\n<td>Optional. Custom message to send. If not including the OTP in this message, set <code>append_otp_to_message</code> to <code>true</code>.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>append_otp_to_message</td>\n<td>json body</td>\n<td>Optional. Set to <code>true</code> to append the OTP to your custom message. Defaults to <code>false</code>.</td>\n<td>No</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>sender_id</td>\n<td>json body</td>\n<td>Optional. Verified sender ID to deliver the OTP. If omitted, a default sender ID is used. Only supported for local numbers currently.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>Note:</strong> If no <code>otp</code> is provided, Relay360 automatically generates one.</p>\n","urlObject":{"path":["verification","sms"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"9fefcf17-7781-4ded-a0ad-5be3dc6be8f3"},{"name":"Initiate WhatsApp Verification Code","id":"d7dbfe6d-6d8d-4e6b-827f-4ad75ea2cce0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdn\": \"+2348124163122\",\n\"otp\": \"1012JK\"\n}"},"url":"{{BASE_URL}}/verification/whatsapp","description":"<p>This endpoint allows you to send a <strong>one-time verification code</strong> via WhatsApp to a registered phone number.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>msisdn</td>\n<td>json body</td>\n<td>The recipient’s phone number in full international format.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>otp</td>\n<td>json body</td>\n<td>Optional. Specify the OTP to send. If not provided, Relay360 will generate one automatically.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>length</td>\n<td>json body</td>\n<td>Optional. Length of the OTP (only used if <code>otp</code> is not provided). Must be 4, 5, 6, 7, or 8.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>expires</td>\n<td>json body</td>\n<td>Optional. Time in minutes before the OTP expires. Default is 10 minutes.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>alphanumeric</td>\n<td>json body</td>\n<td>Optional. Set to <code>true</code> if the OTP should include letters. Only valid if <code>otp</code> is not provided. Defaults to <code>false</code>.</td>\n<td>No</td>\n<td>boolean</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>Note:</strong> If no <code>otp</code> is provided, Relay360 automatically generates one.</p>\n","urlObject":{"path":["verification","whatsapp"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"d7dbfe6d-6d8d-4e6b-827f-4ad75ea2cce0"},{"name":"Initiate Email Verification Code","id":"c7f40aff-9366-4ec8-b44e-c8177b9000bb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"email\": \"josholatunde@gmail.com\",\n\"otp\": \"1012JK\",\n\"from_email\": \"no-reply@lafira.pro\",\n\"from_name\": \"Lafira\"\n}"},"url":"{{BASE_URL}}/verification/email","description":"<p>This endpoint allows you to send a <strong>one-time verification code</strong> via email. Before sending an email verification code, ensure you have <strong>added and verified a sending domain</strong> on your Relay360 dashboard. Verified senders guarantee deliverability and compliance with email standards.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>email</td>\n<td>json body</td>\n<td>The recipient’s email</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>otp</td>\n<td>json body</td>\n<td>Optional. Specify the OTP to send. If not provided, Relay360 will generate one automatically.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>from_email</td>\n<td>json body</td>\n<td>The \"from\" email address. Domain must be verified. e.g <a href=\"https://mailto:no-reply@verified.domain\">no-reply@verified.domain</a></td>\n<td>Yes</td>\n<td>email</td>\n</tr>\n<tr>\n<td>from_name</td>\n<td>json body</td>\n<td>Display name for the sender.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>length</td>\n<td>json body</td>\n<td>Optional. Length of the OTP (only used if <code>otp</code> is not provided). Must be 4, 5, 6, 7, or 8.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>expires</td>\n<td>json body</td>\n<td>Optional. Time in minutes before the OTP expires. Default is 10 minutes.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>alphanumeric</td>\n<td>json body</td>\n<td>Optional. Set to <code>true</code> if the OTP should include letters. Only valid if <code>otp</code> is not provided. Defaults to <code>false</code>.</td>\n<td>No</td>\n<td>boolean</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>Note:</strong> If no <code>otp</code> is provided, Relay360 automatically generates one.</p>\n","urlObject":{"path":["verification","email"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"3b6d528a-f010-4dfb-92e0-a43d6f77209e","name":"Initiate Email Verification Code","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"email\": \"josholatunde@gmail.com\",\n\"otp\": \"1012JK\",\n\"from_email\": \"no-reply@lafira.pro\",\n\"from_name\": \"Lafira\"\n}"},"url":"{{BASE_URL}}/verification/email"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 00:21:20 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"message\": \"OTP email sent successfully\",\n    \"session_id\": \"7575245540371420161\"\n}"}],"_postman_id":"c7f40aff-9366-4ec8-b44e-c8177b9000bb"},{"name":"Initiate Voice Verification Code","id":"29c2987d-1c4b-414b-820d-4231b4ccb6fc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdn\": \"+2348124163122\",\n\"otp\": \"1012JK\"\n}"},"url":"{{BASE_URL}}/verification/voice","description":"<p>This endpoint allows you to send a <strong>one-time verification code</strong> as a voice call to a phone number.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>msisdn</td>\n<td>json body</td>\n<td>The recipient’s phone number in full international format.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>otp</td>\n<td>json body</td>\n<td>Optional. Specify the OTP to send. If not provided, Relay360 will generate one automatically.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>length</td>\n<td>json body</td>\n<td>Optional. Length of the OTP (only used if <code>otp</code> is not provided). Must be 4, 5, 6, 7, or 8.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>expires</td>\n<td>json body</td>\n<td>Optional. Time in minutes before the OTP expires. Default is 10 minutes.</td>\n<td>No</td>\n<td>integer</td>\n</tr>\n<tr>\n<td>alphanumeric</td>\n<td>json body</td>\n<td>Optional. Set to <code>true</code> if the OTP should include letters. Only valid if <code>otp</code> is not provided. Defaults to <code>false</code>.</td>\n<td>No</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>message</td>\n<td>json body</td>\n<td>Optional. Custom message to read during the call. Must include the OTP in the message content.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>webhook_url</td>\n<td>json body</td>\n<td>Optional. URL to receive success/failure callbacks for this OTP request.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>Note:</strong> If no <code>otp</code> is provided, Relay360 automatically generates one.</p>\n","urlObject":{"path":["verification","voice"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"29c2987d-1c4b-414b-820d-4231b4ccb6fc"},{"name":"Verify Code","id":"5cf64d4c-777a-42a0-80f8-6481bf08e124","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"email\": \"josholatunde@gmail.com\",\n\"otp\": \"3497\"\n}"},"url":"{{BASE_URL}}/verification/verify","description":"<p>After sending a one-time verification code via <strong>SMS</strong> or <strong>Voice</strong>, you can use this endpoint to validate the code provided by the user.</p>\n<hr />\n<h3 id=\"header-parameters\"><strong>Header Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>header</td>\n<td><code>Bearer</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n<tr>\n<td>Content-Type</td>\n<td>header</td>\n<td><code>application/json</code></td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"body-parameters\"><strong>Body Parameters</strong></h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>Located In</th>\n<th>Description</th>\n<th>Required</th>\n<th>Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>msisdn</td>\n<td>json body</td>\n<td>The phone number that received the verification code.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>email</td>\n<td>json body</td>\n<td>The email that received the verification code.</td>\n<td>No</td>\n<td>string</td>\n</tr>\n<tr>\n<td>otp</td>\n<td>json body</td>\n<td>The verification code to validate.</td>\n<td>Yes</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>Notes:</strong></p>\n<ul>\n<li><p>This endpoint supports verification for codes sent via <strong>SMS, WhatsApp, Email</strong> or <strong>Voice</strong> channels.</p>\n</li>\n<li><p>For codes sent via <strong>SMS, WhatsApp</strong> or <strong>Voice</strong> channels you must supply the <code>msisdn</code> parameter. For codes sent via the <strong>Email</strong> channel, you must supply the <code>email</code> parameter</p>\n</li>\n<li><p>A successful response confirms the OTP is valid and within its expiration period.</p>\n</li>\n</ul>\n","urlObject":{"path":["verification","verify"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"9ef9c045-8c85-4d49-a4ea-748e8dcb8e89","name":"Verify Code - Expired","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"msisdn\": \"+2348124163122\",\n\"otp\": \"1012JK\"\n}"},"url":"{{BASE_URL}}/verification/verify"},"status":"Bad Request","code":400,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 01:31:07 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": false,\n    \"data\": {\n        \"id\": 46,\n        \"client_id\": \"12\",\n        \"msisdn\": \"+2348124163122\",\n        \"email\": null,\n        \"type\": \"whatsapp\",\n        \"status\": \"expired\",\n        \"expires_at\": \"2022-11-07 20:09:17\",\n        \"created_at\": \"2022-11-07T17:59:17.000000Z\",\n        \"updated_at\": \"2025-11-29T01:31:07.000000Z\",\n        \"session_id\": \"356089\",\n        \"message\": null,\n        \"duration_in_seconds\": null,\n        \"ussd_suffix_code\": null,\n        \"generated_by\": \"Client\",\n        \"deliverystatus\": \"success\",\n        \"local_cost\": \"3.5\",\n        \"webhook_url\": null,\n        \"deliverycost\": \"8\"\n    },\n    \"error\": \"The supplied OTP has expired\"\n}"},{"id":"e14eae21-bd1b-46f3-bfa6-32e43243713c","name":"Verify Code - Success","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\"email\": \"josholatunde@gmail.com\",\n\"otp\": \"3497\"\n}"},"url":"{{BASE_URL}}/verification/verify"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sat, 29 Nov 2025 01:41:34 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"598"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": true,\n    \"data\": {\n        \"id\": 60,\n        \"client_id\": \"38\",\n        \"msisdn\": \"\",\n        \"email\": \"josholatunde@gmail.com\",\n        \"type\": \"email\",\n        \"status\": \"verified\",\n        \"expires_at\": \"2025-11-29 02:50:56\",\n        \"created_at\": \"2025-11-29T01:40:56.000000Z\",\n        \"updated_at\": \"2025-11-29T01:41:34.000000Z\",\n        \"session_id\": \"7575243195319306417\",\n        \"message\": null,\n        \"duration_in_seconds\": null,\n        \"ussd_suffix_code\": null,\n        \"generated_by\": \"Provider\",\n        \"deliverystatus\": \"success\",\n        \"local_cost\": \"0.50\",\n        \"webhook_url\": null,\n        \"deliverycost\": \"5\"\n    },\n    \"message\": \"OTP is verified successfuly\"\n}"}],"_postman_id":"5cf64d4c-777a-42a0-80f8-6481bf08e124"}],"id":"92a63a0e-9f6b-427b-8981-c8cb3b48659d","description":"<p>The Verification APIs allow you to add secure user verification to your web or mobile applications. You can deliver <strong>one-time codes</strong> via <strong>SMS, WhatsApp, Email</strong> or <strong>Voice calls</strong>, and verify them programmatically.</p>\n<p>These APIs are ideal for:</p>\n<ul>\n<li><p>User authentication</p>\n</li>\n<li><p>Transaction verification</p>\n</li>\n<li><p>Multi-factor authentication</p>\n</li>\n<li><p>Any scenario requiring temporary, secure access codes</p>\n</li>\n</ul>\n","_postman_id":"92a63a0e-9f6b-427b-8981-c8cb3b48659d"},{"name":"Resources","item":[{"name":"Get Available Phone Numbers","id":"c003fea6-c78e-4939-8df8-206f2330568f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/phones?page=1","description":"<p>Returns a list of phone numbers associated with your Relay360 account. You can request a phone number from your <a href=\"https://relay360.dev\">Relay360</a> dashboard.</p>\n<p><strong>Usage:</strong><br />Use the <strong>phone_number</strong> value when dispatching a <strong>voice</strong> message or verification code. The phone number will appear as the caller ID.</p>\n","urlObject":{"path":["clients","resources","phones"],"host":["{{BASE_URL}}"],"query":[{"key":"page","value":"1"}],"variable":[]}},"response":[{"id":"35e65563-39a7-49b4-89ee-4ef69d9366d6","name":"Get Phone numbers","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/phones"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Wed, 03 Dec 2025 01:29:01 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"current_page\": 1,\n    \"data\": [\n        {\n            \"id\": 3,\n            \"client_id\": \"38\",\n            \"phone_number\": \"2348000000002\",\n            \"status\": \"approved\",\n            \"created_at\": \"2025-12-02T23:25:35.000000Z\",\n            \"updated_at\": \"2025-12-02T23:25:35.000000Z\",\n            \"provider\": \"default\",\n            \"description\": \"Voice authentication and campaign for our users. Dam.\",\n            \"consent_letter\": \"consent_letters/1764717935_Relay360_Phone_Number_Consent_Template.docx\",\n            \"rejection_reason\": null,\n            \"approved_at\": null\n        }\n    ],\n    \"first_page_url\": \"http://localhost:8000/v1/clients/resources/phones?page=1\",\n    \"from\": 1,\n    \"last_page\": 1,\n    \"last_page_url\": \"http://localhost:8000/v1/clients/resources/phones?page=1\",\n    \"links\": [\n        {\n            \"url\": null,\n            \"label\": \"&laquo; Previous\",\n            \"active\": false\n        },\n        {\n            \"url\": \"http://localhost:8000/v1/clients/resources/phones?page=1\",\n            \"label\": \"1\",\n            \"active\": true\n        },\n        {\n            \"url\": null,\n            \"label\": \"Next &raquo;\",\n            \"active\": false\n        }\n    ],\n    \"next_page_url\": null,\n    \"path\": \"http://localhost:8000/v1/clients/resources/phones\",\n    \"per_page\": 15,\n    \"prev_page_url\": null,\n    \"to\": 1,\n    \"total\": 1\n}"}],"_postman_id":"c003fea6-c78e-4939-8df8-206f2330568f"},{"name":"Get Available Phonebooks","id":"8d3c731f-3e60-400f-97f0-cf38443c00e3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/phonebooks","description":"<p>Returns a list of your saved phonebooks. You can create a phonebook from your <a href=\"https://relay360.dev\">Relay360</a> dashboard.</p>\n<p><strong>Usage:</strong><br />Use the <strong>id</strong> value as the recipient source when dispatching <strong>SMS</strong>, <strong>Voice</strong>, or <strong>WhatsApp</strong> messages.<br />This serves as an alternative to manually supplying a list of phone numbers.</p>\n","urlObject":{"path":["clients","resources","phonebooks"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"89220545-a935-400d-abcd-36cb5f798698","name":"Get Available Phonebooks","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/phonebooks"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Wed, 03 Dec 2025 01:30:37 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"current_page\": 1,\n    \"data\": [\n        {\n            \"id\": 16,\n            \"name\": \"example\",\n            \"client_id\": 38,\n            \"msisdns\": \"+2348124163122,+2348133150074\",\n            \"created_at\": \"2025-11-22T11:55:10.000000Z\",\n            \"updated_at\": \"2025-11-22T11:55:10.000000Z\",\n            \"total\": 2\n        },\n        {\n            \"id\": 18,\n            \"name\": \"list\",\n            \"client_id\": 38,\n            \"msisdns\": \"+2348012345678,+2348087654321,+2347012345678\",\n            \"created_at\": \"2025-11-25T18:30:33.000000Z\",\n            \"updated_at\": \"2025-11-25T18:30:33.000000Z\",\n            \"total\": 3\n        }\n    ],\n    \"first_page_url\": \"http://localhost:8000/v1/clients/resources/phonebooks?page=1\",\n    \"from\": 1,\n    \"last_page\": 1,\n    \"last_page_url\": \"http://localhost:8000/v1/clients/resources/phonebooks?page=1\",\n    \"links\": [\n        {\n            \"url\": null,\n            \"label\": \"&laquo; Previous\",\n            \"active\": false\n        },\n        {\n            \"url\": \"http://localhost:8000/v1/clients/resources/phonebooks?page=1\",\n            \"label\": \"1\",\n            \"active\": true\n        },\n        {\n            \"url\": null,\n            \"label\": \"Next &raquo;\",\n            \"active\": false\n        }\n    ],\n    \"next_page_url\": null,\n    \"path\": \"http://localhost:8000/v1/clients/resources/phonebooks\",\n    \"per_page\": 15,\n    \"prev_page_url\": null,\n    \"to\": 2,\n    \"total\": 2\n}"}],"_postman_id":"8d3c731f-3e60-400f-97f0-cf38443c00e3"},{"name":"Get Available Sender IDs","id":"25741f17-e3cd-4c6d-8c51-4cc3dbc12850","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/senderids","description":"<p>Returns the SMS sender IDs that are approved and available on your Relay360 account.</p>\n<p><strong>Usage:</strong><br />Use the <strong>sender_id</strong> value when dispatching <strong>SMS</strong> messages.</p>\n<ul>\n<li><p>Required for standard SMS broadcasts</p>\n</li>\n<li><p>Optional for <strong>verification/OTP SMS</strong></p>\n</li>\n</ul>\n","urlObject":{"path":["clients","resources","senderids"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"d4a06024-7f67-4194-aea0-c18745f972e0","name":"Get Available Sender IDs","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/senderids"},"status":"OK","code":200,"_postman_previewlanguage":null,"header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Wed, 03 Dec 2025 01:32:53 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"598"}],"cookie":[],"responseTime":null,"body":"{\n    \"current_page\": 1,\n    \"data\": [\n        {\n            \"id\": 13,\n            \"client_id\": \"38\",\n            \"sender_id\": \"MyStyle\",\n            \"description\": \"Logistics business\",\n            \"status\": \"verified\",\n            \"created_at\": \"2025-11-21T21:18:40.000000Z\",\n            \"updated_at\": \"2025-11-21T21:18:40.000000Z\",\n            \"sms_unit_cost\": null,\n            \"sms_otp_unit_cost\": null\n        }\n    ],\n    \"first_page_url\": \"http://localhost:8000/v1/clients/resources/senderids?page=1\",\n    \"from\": 1,\n    \"last_page\": 1,\n    \"last_page_url\": \"http://localhost:8000/v1/clients/resources/senderids?page=1\",\n    \"links\": [\n        {\n            \"url\": null,\n            \"label\": \"&laquo; Previous\",\n            \"active\": false\n        },\n        {\n            \"url\": \"http://localhost:8000/v1/clients/resources/senderids?page=1\",\n            \"label\": \"1\",\n            \"active\": true\n        },\n        {\n            \"url\": null,\n            \"label\": \"Next &raquo;\",\n            \"active\": false\n        }\n    ],\n    \"next_page_url\": null,\n    \"path\": \"http://localhost:8000/v1/clients/resources/senderids\",\n    \"per_page\": 15,\n    \"prev_page_url\": null,\n    \"to\": 1,\n    \"total\": 1\n}"}],"_postman_id":"25741f17-e3cd-4c6d-8c51-4cc3dbc12850"},{"name":"Get Approved WhatsApp Templates","id":"ef33cd90-c2fa-41ba-a4e5-c6d419615944","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/whatsapp-templates","description":"<p>Returns a list of your approved WhatsApp templates. You can create a whatsapp template from your <a href=\"https://relay360.dev\">Relay360</a> dashboard.</p>\n<p><strong>Usage:</strong><br />Use the value of the <code>template</code> prop in each template object as the template parameter when dispatching <strong>WhatsApp</strong> messages.</p>\n<ul>\n<li>Required for standard WhatsApp broadcasts</li>\n<li>Optional for <strong>Whatsapp verification/OTP</strong></li>\n</ul>\n","urlObject":{"path":["clients","resources","whatsapp-templates"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"091da81b-3630-4481-88ef-65a32677d820","name":"Get Approved WhatsApp templates","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/whatsapp-templates"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Sun, 07 Dec 2025 22:12:08 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"data\": {\n        \"current_page\": 1,\n        \"data\": [\n            {\n                \"id\": 6,\n                \"client_id\": \"38\",\n                \"template\": \"hello_universe\",\n                \"message\": \"Hello {{1}}, Have a good day.\\n[requires-image-url-attachment]\",\n                \"status\": \"verified\",\n                \"created_at\": \"2025-11-22T12:45:37.000000Z\",\n                \"updated_at\": \"2025-11-22T12:45:37.000000Z\",\n                \"template_id\": \"hello_world12\"\n            },\n            {\n                \"id\": 7,\n                \"client_id\": \"38\",\n                \"template\": \"hello_world\",\n                \"message\": \"Hello World\\nWelcome and congratulations!! This message demonstrates your ability to send a WhatsApp message notification from the Cloud API, hosted by Meta. Thank you for taking the time to test with us.\",\n                \"status\": \"verified\",\n                \"created_at\": \"2025-11-24T19:29:48.000000Z\",\n                \"updated_at\": \"2025-11-24T19:29:48.000000Z\",\n                \"template_id\": \"hello_world\"\n            }\n        ],\n        \"first_page_url\": \"http://localhost:8000/v1/clients/resources/whatsapp-templates?page=1\",\n        \"from\": 1,\n        \"last_page\": 1,\n        \"last_page_url\": \"http://localhost:8000/v1/clients/resources/whatsapp-templates?page=1\",\n        \"links\": [\n            {\n                \"url\": null,\n                \"label\": \"&laquo; Previous\",\n                \"active\": false\n            },\n            {\n                \"url\": \"http://localhost:8000/v1/clients/resources/whatsapp-templates?page=1\",\n                \"label\": \"1\",\n                \"active\": true\n            },\n            {\n                \"url\": null,\n                \"label\": \"Next &raquo;\",\n                \"active\": false\n            }\n        ],\n        \"next_page_url\": null,\n        \"path\": \"http://localhost:8000/v1/clients/resources/whatsapp-templates\",\n        \"per_page\": 15,\n        \"prev_page_url\": null,\n        \"to\": 2,\n        \"total\": 2\n    },\n    \"status\": true\n}"}],"_postman_id":"ef33cd90-c2fa-41ba-a4e5-c6d419615944"},{"name":"Get Verified Email Domains","id":"e2f1bcd3-c819-4256-8816-61bae37e7da3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/email-domains","description":"<p>Returns a list of your verified email domains. You can create a whatsapp template from your <a href=\"https://relay360.dev\">Relay360</a> dashboard.</p>\n<p><strong>Usage:</strong><br />Use the value of the <code>template</code> prop in each template object as the template parameter when dispatching <strong>WhatsApp</strong> messages.</p>\n<ul>\n<li>Required for standard WhatsApp broadcasts</li>\n<li>Optional for <strong>Whatsapp verification/OTP</strong></li>\n</ul>\n","urlObject":{"path":["clients","resources","email-domains"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"b3b792c3-219f-4278-8773-52feec618bdc","name":"Get Verified Email Domains","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/email-domains"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Wed, 10 Dec 2025 21:47:56 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"data\": {\n        \"current_page\": 1,\n        \"data\": [\n            {\n                \"id\": 4,\n                \"client_id\": 38,\n                \"domain_name\": \"lafira.pro\",\n                \"bird_domain_id\": \"lafira.pro\",\n                \"status\": \"verified\",\n                \"verification_method\": \"DNS\",\n                \"verification_token\": null,\n                \"dns_records\": {\n                    \"txt\": null,\n                    \"spf\": \"v=spf1 include:sparkpostmail.com ~all\",\n                    \"dkim\": \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh5gtIuK0n/iZL606M8uwOQOduR9HQntRYf97aN9fmnpRs5xTFs18Yp7bsCdBnl6lr0DaQc5ZZgoVOJrc6JUAYu9aN7fY/P7nzxNdQGyZnVwolCUuOS6NfOaDdTUVbVFim+b+wN6ehrQgZXhDWp3sK7Yf/f7FOQiGmwj6jMxYyhQIDAQAB\",\n                    \"dmarc\": \"v=DMARC1; p=none; rua=mailto:dmarc@lafira.pro\",\n                    \"full\": [\n                        {\n                            \"type\": \"TXT\",\n                            \"hostname\": \"scph1125\",\n                            \"value\": \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh5gtIuK0n/iZL606M8uwOQOduR9HQntRYf97aN9fmnpRs5xTFs18Yp7bsCdBnl6lr0DaQc5ZZgoVOJrc6JUAYu9aN7fY/P7nzxNdQGyZnVwolCUuOS6NfOaDdTUVbVFim+b+wN6ehrQgZXhDWp3sK7Yf/f7FOQiGmwj6jMxYyhQIDAQAB\"\n                        },\n                        {\n                            \"type\": \"TXT\",\n                            \"hostname\": \"@\",\n                            \"value\": \"v=spf1 include:sparkpostmail.com ~all\"\n                        },\n                        {\n                            \"type\": \"TXT\",\n                            \"hostname\": \"_dmarc\",\n                            \"value\": \"v=DMARC1; p=none; rua=mailto:dmarc@lafira.pro\"\n                        }\n                    ]\n                },\n                \"failure_reason\": null,\n                \"verified_at\": \"2025-11-29T00:00:20.000000Z\",\n                \"last_verified_at\": \"2025-11-29T00:00:20.000000Z\",\n                \"created_at\": \"2025-11-28T23:40:12.000000Z\",\n                \"updated_at\": \"2025-11-29T00:00:20.000000Z\"\n            }\n        ],\n        \"first_page_url\": \"http://localhost:8000/v1/clients/resources/email-domains?page=1\",\n        \"from\": 1,\n        \"last_page\": 1,\n        \"last_page_url\": \"http://localhost:8000/v1/clients/resources/email-domains?page=1\",\n        \"links\": [\n            {\n                \"url\": null,\n                \"label\": \"&laquo; Previous\",\n                \"active\": false\n            },\n            {\n                \"url\": \"http://localhost:8000/v1/clients/resources/email-domains?page=1\",\n                \"label\": \"1\",\n                \"active\": true\n            },\n            {\n                \"url\": null,\n                \"label\": \"Next &raquo;\",\n                \"active\": false\n            }\n        ],\n        \"next_page_url\": null,\n        \"path\": \"http://localhost:8000/v1/clients/resources/email-domains\",\n        \"per_page\": 15,\n        \"prev_page_url\": null,\n        \"to\": 1,\n        \"total\": 1\n    },\n    \"status\": true\n}"}],"_postman_id":"e2f1bcd3-c819-4256-8816-61bae37e7da3"},{"name":"Get Account Info","id":"036257a6-0a79-46a0-b254-6e4fd05a687c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/summary","description":"<p><strong>Get basic info about your account</strong></p>\n","urlObject":{"path":["clients","resources","summary"],"host":["{{BASE_URL}}"],"query":[],"variable":[]}},"response":[{"id":"dc0137dc-7129-4b02-a066-2da4c5bca0ab","name":"Get Account Info","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{API_KEY}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":""},"url":"{{BASE_URL}}/clients/resources/summary"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Host","value":"localhost:8000"},{"key":"Connection","value":"close"},{"key":"X-Powered-By","value":"PHP/8.1.32"},{"key":"Cache-Control","value":"no-cache, private"},{"key":"Date","value":"Wed, 10 Dec 2025 22:00:00 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS, PUT, DELETE"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Access-Control-Allow-Headers","value":"Content-Type, Accept, Authorization, X-Requested-With"},{"key":"X-RateLimit-Limit","value":"600"},{"key":"X-RateLimit-Remaining","value":"599"}],"cookie":[],"responseTime":null,"body":"{\n    \"data\": {\n        \"airtime_balance\": 6021.5,\n        \"name\": \"Escobar\",\n        \"client_id\": 38,\n        \"email\": \"femiinstructor@2200freefonts.com\",\n        \"phone_number\": \"+2349876543234\",\n        \"contact_person\": \"Em Jay\",\n        \"date_joined\": \"21 Nov 2025\"\n    },\n    \"status\": true\n}"}],"_postman_id":"036257a6-0a79-46a0-b254-6e4fd05a687c"}],"id":"bfa5305a-6b92-4ccf-98f6-552942e2f220","description":"<p>The Resources section provides all account-specific assets needed for messaging: approved sender IDs, available phone numbers, and saved phonebooks.<br />Your application references these values when dispatching SMS, Voice, WhatsApp, or Email messages.</p>\n<p>It also provides an endpoint that returns basic info about your account.</p>\n","_postman_id":"bfa5305a-6b92-4ccf-98f6-552942e2f220"},{"name":"Webhooks","item":[{"name":"SMS Dispatch Webhook","id":"85ea821c-429c-48ba-9b6c-1575ff8aef13","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<p>When you create an SMS Dispatch Job and specify a <code>webhook_url</code> in your request, Relay360 will send webhook notifications to that URL for important delivery events.</p>\n<p>These events help you track real-time delivery behavior for every SMS recipient in a dispatch job.</p>\n<p>A webhook request is sent whenever the delivery status of a message changes.</p>\n<p>Statuses may include:<br /><code>sent</code>, <code>submitted</code>, <code>buffered</code>, <code>success</code>, <code>failed</code>, <code>rejected</code>, <code>absentsubscriber</code>, <code>expired</code>.</p>\n<p>(See the <em>SMS Status Reference</em> section for detailed meanings.)</p>\n<hr />\n<h2 id=\"http-request\"><strong>HTTP Request</strong></h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST {webhook_url}\nContent-Type: application/json\n\n</code></pre><hr />\n<h2 id=\"example-webhook-payload-sms-dispatch\"><strong>Example Webhook Payload (SMS Dispatch)</strong></h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"event\": \"dispatch.sms\",\n  \"data\": {\n    \"id\": 93722,\n    \"job_id\": 4410,\n    \"client_id\": 110,\n    \"msisdn\": \"+2348000000000\",\n    \"message_text\": \"Hello, thanks for using Relay360!\",\n    \"run_time\": \"2025-01-18T12:45:22Z\",\n    \"created_at\": \"2025-01-18T12:45:22Z\",\n    \"updated_at\": \"2025-01-18T12:46:03Z\",\n    \"status\": \"success\",\n    \"status_text\": null,\n    \"cost\": 4.5,\n    \"external_id\": \"78922de8-1c4c-44bc-ba92-3bcdbd4c12c1\"\n  }\n}\n\n</code></pre><hr />\n<h2 id=\"response-guide\"><strong>Response Guide</strong></h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>event</strong></td>\n<td>Always <code>\"dispatch.sms\"</code> for SMS Dispatch events.</td>\n</tr>\n<tr>\n<td><strong>id</strong></td>\n<td>Unique ID for the SMS record in Relay360.</td>\n</tr>\n<tr>\n<td><strong>job_id</strong></td>\n<td>ID of the dispatch job the message belongs to.</td>\n</tr>\n<tr>\n<td><strong>client_id</strong></td>\n<td>Your Relay360 Client ID.</td>\n</tr>\n<tr>\n<td><strong>msisdn</strong></td>\n<td>Recipient phone number.</td>\n</tr>\n<tr>\n<td><strong>message_text</strong></td>\n<td>Content of the SMS message.</td>\n</tr>\n<tr>\n<td><strong>run_time</strong></td>\n<td>When the message was executed (instant or scheduled).</td>\n</tr>\n<tr>\n<td><strong>status</strong></td>\n<td>Delivery state of the SMS (see status guide).</td>\n</tr>\n<tr>\n<td><strong>status_text</strong></td>\n<td>Additional telco explanation when applicable (e.g., failure reason).</td>\n</tr>\n<tr>\n<td><strong>cost</strong></td>\n<td>Cost charged for sending the message.</td>\n</tr>\n<tr>\n<td><strong>external_id</strong></td>\n<td>Third-party provider ID for traceability.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"85ea821c-429c-48ba-9b6c-1575ff8aef13"},{"name":"SMS Verification Webhook","id":"4d59916a-fed4-4f3d-a1f8-b2a23d18df28","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<p>When you initiate an <strong>SMS Verification Request</strong> and include a <code>webhook_url</code>, Relay360 sends webhook events for delivery updates.</p>\n<p>These events indicate whether the OTP SMS was successfully delivered to the end user.</p>\n<p>A webhook request is sent <strong>only when a delivery outcome occurs</strong>, such as:</p>\n<p><code>success</code>, <code>failed</code>, <code>rejected</code>, <code>absentsubscriber</code>, <code>expired</code>.</p>\n<hr />\n<h2 id=\"http-request\"><strong>HTTP Request</strong></h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST {webhook_url}\nContent-Type: application/json\n\n</code></pre><hr />\n<h2 id=\"example-webhook-payload-sms-verification\"><strong>Example Webhook Payload (SMS Verification)</strong></h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"event\": \"verification.sms\",\n  \"data\": {\n    \"id\": 118822,\n    \"client_id\": 110,\n    \"msisdn\": \"+2348000000000\",\n    \"expires_at\": \"2025-01-18T12:59:00Z\",\n    \"created_at\": \"2025-01-18T12:49:00Z\",\n    \"updated_at\": \"2025-01-18T12:49:45Z\",\n    \"deliverystatus\": \"success\",\n    \"status\": \"verified\",\n    \"status_text\": null,\n    \"generated_by\": \"Provider\"\n  }\n}\n\n</code></pre><hr />\n<h2 id=\"response-guide\"><strong>Response Guide</strong></h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>event</strong></td>\n<td>Always <code>\"verification.sms\"</code> for SMS OTP webhooks.</td>\n</tr>\n<tr>\n<td><strong>id</strong></td>\n<td>Unique OTP record ID.</td>\n</tr>\n<tr>\n<td><strong>client_id</strong></td>\n<td>Your Relay360 Client ID.</td>\n</tr>\n<tr>\n<td><strong>msisdn</strong></td>\n<td>The phone number the OTP was sent to.</td>\n</tr>\n<tr>\n<td>created_at</td>\n<td>When the Verification was initiated</td>\n</tr>\n<tr>\n<td>updated_at</td>\n<td>When the Verification job was last updated</td>\n</tr>\n<tr>\n<td><strong>expires_at</strong></td>\n<td>Timestamp when the OTP becomes invalid.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>The current verification status of the OTP. Can be <code>new</code>, <code>expired</code> or <code>verified</code>.</td>\n</tr>\n<tr>\n<td><strong>deliverystatus</strong></td>\n<td>Delivery outcome for the OTP SMS. More info in the SMS status reference section.</td>\n</tr>\n<tr>\n<td><strong>status_text</strong></td>\n<td>Additional explanation for failed/rejected messages (if available).</td>\n</tr>\n<tr>\n<td><strong>generated_by</strong></td>\n<td><code>\"Client\"</code> if you supplied the OTP, <code>\"Provider\"</code> if Relay360 generated it.</td>\n</tr>\n</tbody>\n</table>\n</div><h1 id=\"sms-status-reference-dispatch--verification\"><strong>SMS Status Reference (Dispatch &amp; Verification)</strong></h1>\n<p>Use this reference to interpret webhook delivery results; the <code>deliverystatus</code> prop in the sms dispatch and sms verification webhook payloads.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>sent</strong></td>\n<td>Message left Relay360 network successfully.</td>\n</tr>\n<tr>\n<td><strong>submitted</strong></td>\n<td>Delivered to the Mobile Service Provider.</td>\n</tr>\n<tr>\n<td><strong>buffered</strong></td>\n<td>Queued by the Mobile Service Provider.</td>\n</tr>\n<tr>\n<td><strong>success</strong></td>\n<td>Delivered to recipient’s handset. <em>(Final)</em></td>\n</tr>\n<tr>\n<td><strong>failed</strong></td>\n<td>Could not be delivered. <em>(Final)</em></td>\n</tr>\n<tr>\n<td><strong>rejected</strong></td>\n<td>Rejected by MSP. <em>(Final)</em></td>\n</tr>\n<tr>\n<td><strong>absentsubscriber</strong></td>\n<td>Handset unreachable (off, no coverage).</td>\n</tr>\n<tr>\n<td><strong>expired</strong></td>\n<td>Telco blocked or discarded the message. <em>(Final)</em></td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"4d59916a-fed4-4f3d-a1f8-b2a23d18df28"},{"name":"Voice Dispatch Webhook","id":"f8b65089-9dc0-4629-aef0-8920eb8c69ae","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<p>When you create a <strong>Voice Dispatch Job</strong> and include the <code>webhook_url</code> parameter, Relay360 will send a webhook event for each call that is successfully placed.</p>\n<h3 id=\"http-request\"><strong>HTTP Request</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST webhook_url\nContent-Type: application/json\n\n</code></pre><h3 id=\"webhook-payload\"><strong>Webhook Payload</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"event\": \"dispatch.voice\",\n  \"data\": {\n    \"id\": 57208,\n    \"name\": \"test\",\n    \"client_id\": 111,\n    \"job_id\": 4584,\n    \"message_audio\": null,\n    \"message_text\": \"Hello to you too\",\n    \"msisdn\": \"+2348000000000\",\n    \"run_time\": \"2022-12-01 02:29:33\",\n    \"created_at\": \"2022-12-01 02:29:34\",\n    \"updated_at\": \"2022-12-01 02:29:46\",\n    \"duration_in_seconds\": 4,\n    \"cost\": 22,\n    \"type\": \"voice\",\n    \"external_id\": \"91b49feb-4642-5b6b-911f-4c874e202d8b\",\n    \"deliverystatus\": \"success\"\n  }\n}\n\n</code></pre><h3 id=\"notes\"><strong>Notes</strong></h3>\n<ul>\n<li><p><code>deliverystatus = \"success\"</code> means the call was successfully placed.</p>\n</li>\n<li><p>The actual time spent on the call is returned in <code>duration_in_seconds</code>.</p>\n</li>\n<li><p>Only successfully placed calls are billable.</p>\n</li>\n</ul>\n","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"f8b65089-9dc0-4629-aef0-8920eb8c69ae"},{"name":"WhatsApp Dispatch Webhook","id":"4f7da6f1-5e3e-4e02-a402-ef9cd835d17d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<h1 id=\"whatsapp-webhook\"><strong>WhatsApp Webhook</strong></h1>\n<p>Relay360 sends WhatsApp delivery events to your webhook URL whenever you initiate a WhatsApp dispatch job and specify the <code>webhook_url</code> parameter.<br />These events allow you to track message progress across all supported WhatsApp statuses.</p>\n<p>Relay360 posts a webhook event <strong>each time the message status changes</strong>, ensuring you always have the latest delivery state.</p>\n<hr />\n<h2 id=\"supported-whatsapp-status-events\"><strong>Supported WhatsApp Status Events</strong></h2>\n<p>Relay360 will send a webhook request when the message transitions into any of the following states:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>sent</strong></td>\n<td>Message has been submitted to the WhatsApp channel provider.</td>\n</tr>\n<tr>\n<td><strong>delivered</strong></td>\n<td>The recipient’s device received the message.</td>\n</tr>\n<tr>\n<td><strong>read</strong></td>\n<td>The recipient opened/read the message.</td>\n</tr>\n<tr>\n<td><strong>failed</strong></td>\n<td>Delivery attempt was unsuccessful.</td>\n</tr>\n<tr>\n<td><strong>deleted</strong></td>\n<td>Message was deleted (by the system or provider).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"webhook-request\"><strong>Webhook Request</strong></h2>\n<p>Whenever a WhatsApp message changes state, Relay360 sends a POST request to your <code>webhook_url</code>.</p>\n<h3 id=\"http-request\"><strong>HTTP Request</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST webhook_url\nContent-Type: application/json\n\n</code></pre><h3 id=\"webhook-payload-example\"><strong>Webhook Payload Example</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n{\n  \"event\": \"dispatch.whatsapp\",\n  \"data\": {\n    \"id\": 12348,\n    \"client_id\": 789,\n    \"job_id\": 459,\n    \"type\": \"whatsapp\",\n    \"msisdn\": \"2348012345678\",\n    \"message_text\": null,\n    \"run_time\": \"2025-12-07 14:30:00\",\n    \"created_at\": \"2025-12-07 14:25:00\",\n    \"updated_at\": \"2025-12-07 14:30:45\",\n    \"cost\": 0,\n    \"external_id\": \"ext_101jkl\",\n    \"deliverystatus\": \"failed\",\n    \"status_text\": \"Invalid phone number; Message expired\",\n    \"delivered_at\": null\n  }\n}\n\n</code></pre>","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"4f7da6f1-5e3e-4e02-a402-ef9cd835d17d"},{"name":"Voice Verification Webhook","id":"e1a76421-5c8b-43fe-b4c9-7b358ac1b2ed","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<p>When you initiate a <strong>Voice Verification</strong> request and include a <code>webhook_url</code>, Relay360 will send a webhook event <strong>only</strong> when the call is successfully placed.</p>\n<h3 id=\"http-request\"><strong>HTTP Request</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST webhook_url\nContent-Type: application/json\n\n</code></pre><h3 id=\"webhook-payload\"><strong>Webhook Payload</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"event\": \"verification.voice\",\n  \"data\": {\n    \"id\": 57208,\n    \"client_id\": 111,\n    \"msisdn\": \"+2348000000000\",\n    \"type\": \"voice\",\n    \"expires_at\": \"2022-12-01 02:39:34\",\n    \"created_at\": \"2022-12-01 02:29:34\",\n    \"updated_at\": \"2022-12-01 02:29:46\",\n    \"message\": null,\n    \"duration_in_seconds\": 4,\n    \"ussd_suffix_code\": null,\n    \"generated_by\": \"Client\",\n    \"deliverystatus\": \"success\"\n  }\n}\n\n</code></pre><h3 id=\"notes\"><strong>Notes</strong></h3>\n<ul>\n<li><p><code>deliverystatus = \"success\"</code> indicates the call was placed successfully.</p>\n</li>\n<li><p>The call duration is provided in <code>duration_in_seconds</code>.</p>\n</li>\n<li><p>Only successful verification calls incur charges.</p>\n</li>\n</ul>\n","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"e1a76421-5c8b-43fe-b4c9-7b358ac1b2ed"},{"name":"WhatsApp Verification Webhook","id":"4febe78e-86b4-436f-8cb7-ccc840a18c13","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"webhook_url","description":"<p>When you initiate a <strong>WhatsApp Verification</strong> request and include a <code>webhook_url</code>, Relay360 will send a webhook event <strong>only</strong> when <strong>the message status changes</strong>, ensuring you always have the latest delivery state.</p>\n<h3 id=\"http-request\"><strong>HTTP Request</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST webhook_url\nContent-Type: application/json\n\n</code></pre><h3 id=\"webhook-payload\"><strong>Webhook Payload</strong></h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"event\": \"verification.whatsapp\",\n  \"data\": {\n    \"id\": 54323,\n    \"client_id\": 789,\n    \"msisdn\": \"2348012345678\",\n    \"type\": \"whatsapp\",\n    \"expires_at\": \"2025-12-07 14:40:00\",\n    \"created_at\": \"2025-12-07 14:30:00\",\n    \"updated_at\": \"2025-12-07 14:30:18\",\n    \"generated_by\": \"Provider\",\n    \"deliverystatus\": \"read\"\n  }\n}\n\n</code></pre><h2 id=\"supported-whatsapp-status-events\"><strong>Supported WhatsApp Status Events</strong></h2>\n<p>Relay360 will send a webhook request when the message transitions into any of the following states:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>sent</strong></td>\n<td>Message has been submitted to the WhatsApp channel provider.</td>\n</tr>\n<tr>\n<td><strong>delivered</strong></td>\n<td>The recipient’s device received the message.</td>\n</tr>\n<tr>\n<td><strong>read</strong></td>\n<td>The recipient opened/read the message.</td>\n</tr>\n<tr>\n<td><strong>failed</strong></td>\n<td>Delivery attempt was unsuccessful.</td>\n</tr>\n<tr>\n<td><strong>deleted</strong></td>\n<td>Message was deleted (by the system or provider).</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"host":["webhook_url"],"query":[],"variable":[]}},"response":[],"_postman_id":"4febe78e-86b4-436f-8cb7-ccc840a18c13"}],"id":"eee447f2-de56-4848-a190-959f511fd209","description":"<p>Relay360 provides a webhook mechanism that allows your application to receive real-time delivery reports for your dispatch and verification jobs.<br />When creating a dispatch job or when initiating a verification request using Voice, SMS, WhatsApp, or Email, you may optionally specify a <code>webhook_url</code>prop.</p>\n<p>If provided, Relay360 will send webhook events to this URL whenever important lifecycle events occur (such as successful call placements or verification results).</p>\n","_postman_id":"eee447f2-de56-4848-a190-959f511fd209"}]}