Send WhatsApp OTP in PHP

WhatsApp verification in PHP — plain or Laravel — is two REST calls: POST /v1/send and POST /v1/verify. The cURL example below runs with no dependencies; a Laravel HTTP client version follows it.

PHP 7.4+ · cURL extension (bundled) · Laravel snippet included

10 free OTPs on signup — no credit card required.

1. Send an OTP

Generate an API key, then POST the destination number to /v1/send. OTP Space returns 202 Accepted once the message is queued for WhatsApp delivery.

otp.php
<?php
// Plain cURL — no Composer packages required (PHP 7.4+).
// The key comes from https://app.otpspace.com/dashboard/api-keys.
// Keep it server-side; never expose it in front-end code.
const OTPSPACE_KEY  = 'sk_live_xxx';
const OTPSPACE_BASE = 'https://api.otpspace.com/v1';

function otpspace_post(string $path, array $payload): array {
    $ch = curl_init(OTPSPACE_BASE . $path);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . OTPSPACE_KEY,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS     => json_encode($payload),
    ]);
    $body   = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ['status' => $status, 'body' => json_decode($body, true)];
}

// Send a WhatsApp OTP to an Indonesian number (E.164, e.g. "+6281234567890").
// OTP Space returns 202 Accepted once the message is queued.
function send_otp(string $phone): bool {
    $res = otpspace_post('/send', ['phone' => $phone]);
    return $res['status'] === 202;
}

// Verify the code the user typed — 200 means it is correct.
function verify_otp(string $phone, string $code): bool {
    $res = otpspace_post('/verify', ['phone' => $phone, 'code' => $code]);
    return $res['status'] === 200;
}

2. Verify the code

POST the same number plus the code the user entered to /v1/verify. A 200 OK means the code is correct; every number gets up to 5 attempts before the OTP locks.

OtpService.php (Laravel)
<?php
// Laravel: use the built-in HTTP client (Illuminate\Support\Facades\Http).
// Put OTPSPACE_KEY in your .env and read it via config/services.php.
namespace App\Services;

use Illuminate\Support\Facades\Http;

class OtpService
{
    private string $base = 'https://api.otpspace.com/v1';

    private function client()
    {
        return Http::withToken(config('services.otpspace.key'))
            ->acceptJson();
    }

    // Send a WhatsApp OTP; true once OTP Space returns 202 Accepted.
    public function send(string $phone): bool
    {
        return $this->client()
            ->post($this->base . '/send', ['phone' => $phone])
            ->status() === 202;
    }

    // Verify the user's code; true on 200 OK.
    public function verify(string $phone, string $code): bool
    {
        return $this->client()
            ->post($this->base . '/verify', ['phone' => $phone, 'code' => $code])
            ->status() === 200;
    }
}

What the API returns

A successful send responds immediately with the masked destination, an otp_id you can track, and your remaining credits.

202 Accepted
{
  "success": true,
  "data": {
    "otp_id": "otp_abc123def456",
    "destination": "6281234***90",
    "channel": "whatsapp",
    "status": "queued",
    "expires_at": "2026-07-17T10:05:00Z"
  },
  "credits_remaining": 994
}

Built for Indonesian apps

OTP Space delivers one-time passwords over WhatsApp to every Indonesian carrier through two REST calls — no WhatsApp Business API setup, no template approvals, no SDK to install. It works the same from any language: sign up, generate a key, and send. The examples here use only the standard library so you can drop them straight into an existing service.

Other languages

Go Node.js

Send your first WhatsApp OTP today

Sign up free, generate your API key, and integrate in two REST calls — no credit card, no sales call, no WhatsApp Business verification.