Machine-readable API documentation for AI/LLM integration
# YOTARO EXTERNAL 2FA API REFERENCE
# Version: 1.0
# Base URL: https://yotaro.tech/api/v1/external-2fa
================================================================================
## AUTHENTICATION
================================================================================
All requests require API key in header:
Header: X-API-Key: <your_api_token>
Token format: 64-character hexadecimal string
Example: X-API-Key: a1b2c3d4e5f6...
================================================================================
## ENDPOINTS OVERVIEW
================================================================================
POST /send - Send verification code to phone number
POST /verify - Verify user-entered code
POST /resend - Resend code to same request
GET /status - Check verification request status
================================================================================
## ENDPOINT: SEND VERIFICATION CODE
================================================================================
POST /api/v1/external-2fa/send
PURPOSE: Send a 6-digit verification code to user's WhatsApp
REQUEST:
Content-Type: application/json
X-API-Key: <token>
Body (JSON):
{
"phone": string, // REQUIRED - Phone number with country code, no + prefix
// Examples: "972501234567" (Israel), "14155551234" (USA)
"context": object // OPTIONAL - Custom data returned in webhook/verify response
// Example: {"user_id": "123", "action": "login"}
}
RESPONSE SUCCESS (200):
{
"success": true,
"message": "Verification code sent",
"data": {
"request_id": string, // IMPORTANT: Save this! Needed for verify/status
"expires_at": string, // ISO datetime when code expires (10 minutes)
"phone_masked": string // Masked phone for display: "972***567"
}
}
RESPONSE ERROR (4xx/5xx):
{
"success": false,
"message": string, // Human-readable error
"errors": object // Validation errors if applicable
}
EXAMPLE CURL:
curl -X POST https://yotaro.tech/api/v1/external-2fa/send \
-H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"phone":"972501234567","context":{"user_id":"123"}}'
================================================================================
## ENDPOINT: VERIFY CODE
================================================================================
POST /api/v1/external-2fa/verify
PURPOSE: Verify the 6-digit code entered by user
REQUEST:
Content-Type: application/json
X-API-Key: <token>
Body (JSON):
{
"request_id": string, // REQUIRED - The request_id from /send response
"code": string // REQUIRED - 6-digit code entered by user
// Example: "123456"
}
RESPONSE SUCCESS (200):
{
"success": true,
"message": "Code verified successfully",
"data": {
"verified": true,
"context": object // Returns the context sent in /send request
}
}
RESPONSE FAILURE - WRONG CODE (400):
{
"success": false,
"message": "Invalid verification code",
"data": {
"verified": false,
"attempts_remaining": number // 0, 1, or 2
}
}
RESPONSE FAILURE - EXPIRED/MAX ATTEMPTS (400):
{
"success": false,
"message": "Verification code has expired" | "Maximum verification attempts exceeded"
}
EXAMPLE CURL:
curl -X POST https://yotaro.tech/api/v1/external-2fa/verify \
-H "X-API-Key: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"request_id":"req_abc123...","code":"123456"}'
================================================================================
## ENDPOINT: CHECK STATUS
================================================================================
GET /api/v1/external-2fa/status?request_id=<request_id>
PURPOSE: Check current status of a verification request
REQUEST:
X-API-Key: <token>
Query param: request_id (required)
RESPONSE (200):
{
"success": true,
"data": {
"status": string, // "pending" | "verified" | "expired" | "failed"
"attempts_used": number, // 0-3
"attempts_remaining": number, // 3-0
"expires_at": string, // ISO datetime
"verified_at": string|null // ISO datetime if verified, null otherwise
}
}
STATUS VALUES:
"pending" - Code sent, waiting for verification
"verified" - Code successfully verified
"expired" - Code expired (after 10 minutes)
"failed" - Max attempts exceeded (3 wrong codes)
EXAMPLE CURL:
curl -X GET "https://yotaro.tech/api/v1/external-2fa/status?request_id=req_abc123" \
-H "X-API-Key: YOUR_TOKEN"
================================================================================
## ENDPOINT: RESEND CODE
================================================================================
POST /api/v1/external-2fa/resend
PURPOSE: Resend verification code to the same phone (new code, new expiry)
REQUEST:
Content-Type: application/json
X-API-Key: <token>
Body (JSON):
{
"request_id": string // REQUIRED - Original request_id
}
RESPONSE: Same as /send endpoint (returns new request_id)
================================================================================
## ERROR CODES
================================================================================
HTTP 400 - Bad Request
- Missing required parameters
- Invalid phone number format
- Invalid code format (not 6 digits)
- Code verification failed
HTTP 401 - Unauthorized
- Missing X-API-Key header
- Invalid API token
- Token disabled or expired
- IP not in whitelist (if configured)
HTTP 404 - Not Found
- request_id not found
- Endpoint not found
HTTP 429 - Too Many Requests
- Daily rate limit exceeded
- Monthly rate limit exceeded
HTTP 500 - Server Error
- WhatsApp message failed to send
- Database error
- Internal error
================================================================================
## RATE LIMITS
================================================================================
Limits are configured per API token:
- Daily limit: Default 100 requests/day
- Monthly limit: Default 3000 requests/month
When limit exceeded:
HTTP 401 with message: "Daily rate limit exceeded" or "Monthly rate limit exceeded"
================================================================================
## WEBHOOK (OPTIONAL)
================================================================================
If webhook URL configured for token, POST request sent on successful verification:
WEBHOOK REQUEST:
POST <your_webhook_url>
Content-Type: application/json
X-Webhook-Signature: <HMAC-SHA256 signature>
Body:
{
"event": "verified",
"request_id": string,
"context": object|null,
"timestamp": string // ISO 8601 format
}
SIGNATURE VERIFICATION (PHP):
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$expected = hash_hmac('sha256', $payload, $your_webhook_secret);
$valid = hash_equals($expected, $signature);
================================================================================
## CODE SPECIFICATIONS
================================================================================
Verification Code:
- Length: 6 digits
- Format: Numeric only (000000-999999)
- Expiry: 10 minutes from send
- Max attempts: 3 wrong codes
Phone Number:
- Format: Country code + number, no + prefix
- Israel: 972XXXXXXXXX (12 digits)
- USA: 1XXXXXXXXXX (11 digits)
- Validation: 9-15 digits
Request ID:
- Format: "req_" + 32 hex characters
- Example: "req_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
================================================================================
## TYPICAL INTEGRATION FLOW
================================================================================
1. USER INITIATES LOGIN/ACTION
Your app collects user's phone number
2. SEND CODE
POST /send with phone number
Save request_id in session/database
3. USER RECEIVES WHATSAPP MESSAGE
Message format: "Your verification code is: 123456"
4. USER ENTERS CODE IN YOUR APP
Your app collects the 6-digit code
5. VERIFY CODE
POST /verify with request_id and code
If success: Proceed with login/action
If failure: Show error, allow retry (check attempts_remaining)
6. (OPTIONAL) WEBHOOK NOTIFICATION
Your server receives confirmation of verification
================================================================================
## LANGUAGE-SPECIFIC EXAMPLES
================================================================================
### PHP
```php
$ch = curl_init('https://yotaro.tech/api/v1/external-2fa/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_TOKEN',
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode([
'phone' => '972501234567',
'context' => ['user_id' => '123']
])
]);
$response = json_decode(curl_exec($ch), true);
$requestId = $response['data']['request_id'];
```
### JavaScript (Node.js)
```javascript
const response = await fetch('https://yotaro.tech/api/v1/external-2fa/send', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone: '972501234567',
context: { user_id: '123' }
})
});
const data = await response.json();
const requestId = data.data.request_id;
```
### Python
```python
import requests
response = requests.post(
'https://yotaro.tech/api/v1/external-2fa/send',
headers={
'X-API-Key': 'YOUR_TOKEN',
'Content-Type': 'application/json'
},
json={
'phone': '972501234567',
'context': {'user_id': '123'}
}
)
data = response.json()
request_id = data['data']['request_id']
```
================================================================================
## NOTES FOR LLM IMPLEMENTATION
================================================================================
1. Always store request_id after /send - required for verify/status
2. Handle all HTTP error codes appropriately
3. Implement retry logic for 500 errors (with backoff)
4. Check attempts_remaining before allowing retry
5. Validate phone format before sending (9-15 digits)
6. Code input should accept only 6 digits
7. Consider webhook for real-time verification status
8. Token never expires unless configured with expires_at
================================================================================
## CONTACT
================================================================================
Support: system@looz.online
Documentation: https://yotaro.tech/docs-external-2fa
================================================================================
{
"openapi": "3.0.0",
"info": {
"title": "Yotaro External 2FA API",
"version": "1.0.0",
"description": "WhatsApp-based 2FA verification service"
},
"servers": [{"url": "https://yotaro.tech/api/v1/external-2fa"}],
"security": [{"apiKey": []}],
"components": {
"securitySchemes": {
"apiKey": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
}
}
},
"paths": {
"/send": {
"post": {
"summary": "Send verification code",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["phone"],
"properties": {
"phone": {"type": "string", "pattern": "^[0-9]{9,15}$"},
"context": {"type": "object"}
}
}
}
}
},
"responses": {
"200": {
"description": "Code sent successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {"type": "boolean"},
"data": {
"type": "object",
"properties": {
"request_id": {"type": "string"},
"expires_at": {"type": "string", "format": "date-time"},
"phone_masked": {"type": "string"}
}
}
}
}
}
}
}
}
}
},
"/verify": {
"post": {
"summary": "Verify code",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["request_id", "code"],
"properties": {
"request_id": {"type": "string"},
"code": {"type": "string", "pattern": "^[0-9]{6}$"}
}
}
}
}
},
"responses": {
"200": {
"description": "Verification result",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {"type": "boolean"},
"data": {
"type": "object",
"properties": {
"verified": {"type": "boolean"},
"context": {"type": "object"},
"attempts_remaining": {"type": "integer"}
}
}
}
}
}
}
}
}
}
},
"/status": {
"get": {
"summary": "Check verification status",
"parameters": [{
"name": "request_id",
"in": "query",
"required": true,
"schema": {"type": "string"}
}],
"responses": {
"200": {
"description": "Status information",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {"type": "boolean"},
"data": {
"type": "object",
"properties": {
"status": {"type": "string", "enum": ["pending", "verified", "expired", "failed"]},
"attempts_used": {"type": "integer"},
"attempts_remaining": {"type": "integer"},
"expires_at": {"type": "string", "format": "date-time"},
"verified_at": {"type": "string", "format": "date-time", "nullable": true}
}
}
}
}
}
}
}
}
}
}
}
}