Skip to content

Verify API

Multi-channel OTP/2FA verification service.

Channels: SMS, Voice (TTS), and Email

Quick Start:

bash
# SMS
curl -X POST https://api.wayscloud.services/v1/verify/start \
  -H "X-API-Key: wayscloud_verify_xxx" \
  -H "Content-Type: application/json" \
  -d '{"channel": "sms", "recipient": "+4712345678", "locale": "no"}'

# Voice (TTS call)
curl -X POST https://api.wayscloud.services/v1/verify/start \
  -H "X-API-Key: wayscloud_verify_xxx" \
  -H "Content-Type: application/json" \
  -d '{"channel": "voice", "recipient": "+4712345678", "locale": "no"}'

# Email
curl -X POST https://api.wayscloud.services/v1/verify/start \
  -H "X-API-Key: wayscloud_verify_xxx" \
  -H "Content-Type: application/json" \
  -d '{"channel": "email", "recipient": "user@example.com", "locale": "no"}'

# Check code
curl -X POST https://api.wayscloud.services/v1/verify/check \
  -H "X-API-Key: wayscloud_verify_xxx" \
  -H "Content-Type: application/json" \
  -d '{"session_id": "...", "code": "123456"}'

Channel Details:

ChannelRecipientSender
smsPhone (E.164)Configurable alphanumeric
voicePhone (E.164)+47 21 53 50 30
emailEmail addressVerified domain or WAYSCloud default

Pricing: 1.25 NOK per session + delivery (SMS ~0.35 NOK, Voice ~0.50 NOK, Email included)

Security:

  • Codes hashed with SHA256 (never stored in plaintext)
  • Max 5 attempts per session
  • TTL: 60-900 seconds (configurable)
  • Tenant isolation

Endpoints

MethodPathDescription
POST/v1/verify/startStart verification
POST/v1/verify/checkCheck verification code
GET/v1/verify/status/{session_id}Get session status
DELETE/v1/verify/sessions/{session_id}Cancel session

POST /v1/verify/start

Start verification

Start a new verification session and send code via SMS, voice call, or email.

Example Request (SMS)

json
{
  "channel": "sms",
  "recipient": "+4712345678",
  "code_length": 6,
  "ttl_seconds": 300,
  "client_reference": "signup-user-42",
  "locale": "no"
}

Example Request (Voice)

json
{
  "channel": "voice",
  "recipient": "+4712345678",
  "locale": "no"
}

Example Request (Email)

json
{
  "channel": "email",
  "recipient": "user@example.com",
  "locale": "no"
}

Parameters

FieldRequiredDefaultDescription
channelNosmsChannel: sms, voice, or email
recipientYes-Phone (E.164) for SMS/Voice, email for Email
code_lengthNo6Code length (4-8 digits)
ttl_secondsNo300Session TTL in seconds (60-900)
client_referenceNo-Your reference for tracking
localeNoenMessage language: en, no, nb, sv, da, fi
metadataNo-Custom metadata object (stored, not processed)
client_ipNo-End-user IP for risk scoring. If provided, ip_risk is included in response

Channel Notes

SMS: Requires sender name configured in dashboard settings.

Voice: Caller ID +47 21 53 50 30. Code read twice. Languages: en, no, sv, da, fi.

Email: From-address is your verified domain or no-reply@wayscloud.net. Verify domain via Domain Verification API to use custom from-address.

Request Body:

FieldTypeDescription
channelstringVerification channel Values: sms, voice, email
recipientstringRequired. Phone (E.164) or email address
code_lengthintegerVerification code length
ttl_secondsintegerSession TTL in seconds
client_referencestringYour tracking reference (e.g., signup-123)
localestringMessage language Values: en, no, nb, sv, da, fi
metadataobjectCustom metadata (stored, not processed)
client_ipstringEnd-user IP for risk scoring. If provided, ip_risk is included in response

Response:

FieldTypeDescription
session_idstring
statusstringValues: pending, delivered
channelstringValues: sms, voice, email
expires_atstring
created_atstring
ip_riskobjectIP risk assessment (only if client_ip provided)

Example:

bash
curl -X POST https://api.wayscloud.services/v1/verify/start \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

POST /v1/verify/check

Check verification code

Verify the code entered by the user.

Example Request

json
{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "code": "123456",
  "client_ip": "203.0.113.42"
}

The client_ip is optional. If provided, the response includes ip_risk with threat assessment data.

Error Codes

ErrorHTTPMeaningUser Action
invalid_code200Wrong code enteredShow remaining attempts
session_expired200Session TTL exceededStart new verification
max_attempts_exceeded2005 attempts usedStart new verification
session_not_found404Invalid session IDCheck session_id
voice_no_answer200Voice call not answeredTry SMS or retry
voice_busy200Phone line busyRetry later

Sessions are automatically locked after 5 failed attempts.

Request Body:

FieldTypeDescription
session_idstringRequired. Session ID from /start response
codestringRequired. Verification code entered by user
client_ipstringEnd-user IP for risk scoring

Response:

FieldTypeDescription
statusstringValues: verified, pending, failed, expired
verified_atstring
errorstringError code if failed
attempts_remainingintegerRemaining attempts
ip_riskobjectIP risk assessment (only if client_ip provided)

Example:

bash
curl -X POST https://api.wayscloud.services/v1/verify/check \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

GET /v1/verify/status/

Get session status

Get current status of a verification session.

Response Fields

FieldDescription
session_idUnique session identifier
channelChannel used: sms or voice
statusCurrent status
recipientFull phone number
attempt_countNumber of /check attempts made
max_attemptsMaximum allowed attempts (5)
client_referenceYour tracking reference

Status Values

  • pending - Session created, delivery in progress
  • delivered - Code sent/played to recipient
  • verified - Successfully verified ✓
  • failed - Max attempts or delivery failed
  • expired - Session TTL exceeded
  • cancelled - Manually cancelled

Response:

FieldTypeDescription
session_idstring
channelstringValues: sms, voice, email
statusstringValues: pending, delivered, verified, failed, expired, cancelled
recipientstring
created_atstring
expires_atstring
delivered_atstring
verified_atstring
attempt_countinteger
max_attemptsinteger
client_referencestring
error_messagestringError details if failed

Example:

bash
curl https://api.wayscloud.services/v1/verify/status/{session_id} \
  -H "X-API-Key: YOUR_API_KEY"

DELETE /v1/verify/sessions/

Cancel session

Cancel a pending or delivered verification session. Cannot cancel verified, failed, or expired sessions.

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/verify/sessions/{session_id} \
  -H "X-API-Key: YOUR_API_KEY"

WAYSCloud AS