Need to verify a WhatsApp number from your Go app? It's two REST calls — POST /v1/send to send the OTP, POST /v1/verify to check the code. The snippet below uses only net/http from the standard library, so you can paste it and go.
10 free OTPs on signup — no credit card required.
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.
package otp
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
// apiKey comes from https://app.otpspace.com/dashboard/api-keys.
// Keep it server-side — never ship it in a mobile or browser client.
const apiKey = "sk_live_xxx"
const baseURL = "https://api.otpspace.com/v1"
// SendOTP sends a WhatsApp OTP to an Indonesian number (E.164, e.g.
// "+6281234567890"). OTP Space replies 202 Accepted once it is queued.
func SendOTP(phone string) error {
payload, _ := json.Marshal(map[string]string{"phone": phone})
req, _ := http.NewRequest(http.MethodPost, baseURL+"/send", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusAccepted { // 202
return fmt.Errorf("otp send failed: %s", res.Status)
}
return nil
}
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.
// VerifyOTP checks the code the user typed against the OTP that was sent to
// their number. A 200 OK means the code is correct; anything else (422 wrong
// code, 410 expired, 429 too many attempts) means it is not.
func VerifyOTP(phone, code string) (bool, error) {
payload, _ := json.Marshal(map[string]string{"phone": phone, "code": code})
req, _ := http.NewRequest(http.MethodPost, baseURL+"/verify", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return false, err
}
defer res.Body.Close()
return res.StatusCode == http.StatusOK, nil // 200 = verified
}
A successful send responds immediately with the masked destination, an otp_id you can track, and your remaining credits.
{
"success": true,
"data": {
"otp_id": "otp_abc123def456",
"destination": "6281234***90",
"channel": "whatsapp",
"status": "queued",
"expires_at": "2026-07-17T10:05:00Z"
},
"credits_remaining": 994
}
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.
Sign up free, generate your API key, and integrate in two REST calls — no credit card, no sales call, no WhatsApp Business verification.