YOTARO EXTERNAL 2FA API - LLM REFERENCE

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

================================================================================

RAW JSON SCHEMA

{
  "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}
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}