Sabong API v1.0

Generate Auth Token API

Overview

The Generate Auth Token API creates a time-limited authentication token for client users. If the client doesn't exist, a new user account is automatically created with wallet initialization. For existing clients, their profile information is updated. The returned token can be used to authenticate the user via a direct login link.

Endpoint

MethodEndpointAuthentication
POST/api/v1/generate-auth-tokenSignature Required

Authentication

This endpoint requires Signature-based Authentication. You must include the following headers:

HeaderDescription
x-signatureHMAC-SHA256 signature of the request
x-timestampUnix timestamp (seconds) when the request was generated

Note: See Overview for detailed information on how signature authentication works and how to generate signatures.

Request Body

FieldTypeRequiredDefaultValidation
clientIdstringYes-Max 255 characters
usernamestringYes-Max 100 characters
displayNamestringYes-Max 100 characters
ipAddressstringYes-Max 45 characters
expirationintegerNo2Min: 1, Max: 1440 (24 hours in minutes)

Request Example

{
  "clientId": "CLIENT_001",
  "username": "testuser001",
  "displayName": "Client One",
  "ipAddress": "192.168.1.100",
  "expiration": 5
}

Response

Success Response (200 OK)

{
  "status": "success",
  "message": "Auth token generated successfully",
  "data": {
    "token": "aB3dE5fGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGh",
    "expiration": "2026-02-01T14:59:42.123Z",
    "expiresIn": 300,
    "loginLink": "https://your-app.com/login/aB3dE5fGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGh",
    "user": {
      "id": 123,
      "username": "testuser001",
      "displayId": "CLIENT_001",
      "displayName": "Client One"
    },
    "isNewUser": true
  }
}

Response Fields

FieldTypeDescription
statusstringAlways "success" for successful requests
messagestringHuman-readable success message
data.tokenstring64-character authentication token
data.expirationstringISO 8601 timestamp when token expires
data.expiresInintegerToken validity duration in seconds
data.loginLinkstringDirect URL for user login with token
data.user.idintegerInternal user ID
data.user.usernamestringUser's username
data.user.displayIdstringClient ID used for display purposes
data.user.displayNamestringUser's display name
data.isNewUserbooleanTrue if a new user was created, false if existing user was updated

Error Responses

Validation Error (400 Bad Request)

{
  "status": "failed",
  "message": "Validation failed",
  "data": {
    "errors": {
      "clientId": ["The clientId field is required."],
      "username": ["The username field is required."],
      "expiration": ["The expiration must be at least 1."]
    }
  }
}

Authentication Error (401 Unauthorized)

{
  "status": "error",
  "message": "Invalid signature",
  "data": null
}

Or when timestamp is expired:

{
  "status": "error",
  "message": "Missing required signature headers or secret",
  "data": null
}

Server Error (500 Internal Server Error)

{
  "status": "failed",
  "message": "Failed to generate auth token",
  "data": {
    "error": "Database connection failed"
  }
}

User Creation & Update Logic

New User Flow

When clientId doesn't exist in the system:

  1. Generate Display ID: Creates a unique referral code (format: REF-YYYY-XXXXXX)
  2. Create User Record:
    • username: From request
    • name: From displayName
    • displayId: Set to clientId
    • clientId: Primary identifier
    • referralCode: Auto-generated
    • password: Random hashed password (temp user)
    • role: "user"
    • status: "active"
  3. Initialize Wallet: Creates a USD wallet for the new user
  4. Generate Token: Creates 64-character random token
  5. Store Token: Saves token with expiration to database

Existing User Flow

When clientId already exists:

  1. Update Profile: Updates name and username fields
  2. Generate Token: Creates new 64-character random token
  3. Store Token: Saves token with expiration to database

Usage Example

cURL

curl -X POST https://wdcf.xerve.online/api/v1/generate-auth-token \
  -H "Content-Type: application/json" \
  -H "x-signature: YOUR_SIGNATURE" \
  -H "x-timestamp: 1706802000" \
  -d '{
    "clientId": "CLIENT_001",
    "username": "testuser001",
    "displayName": "Client One",
    "ipAddress": "192.168.1.100",
    "expiration": 5
  }'

Note: To generate the signature, refer to the Overview documentation.

JavaScript/TypeScript (with Axios)

import axios from 'axios';
// Import your signature generation function (see Overview)
import { generateSignature } from './signature-utils';

const API_BASE_URL = 'https://wdcf.xerve.online';
const CLIENT_SECRET = 'your-secret-key';

async function generateAuthToken() {
  const timestamp = Math.floor(Date.now() / 1000);
  const payload = {
    clientId: 'CLIENT_001',
    username: 'testuser001',
    displayName: 'Client One',
    ipAddress: '192.168.1.100',
    expiration: 5
  };

  // Generate signature (see Overview for implementation)
  const signature = generateSignature({
    method: 'POST',
    path: '/api/v1/generate-auth-token',
    payload,
    secret: CLIENT_SECRET,
    timestamp
  });

  try {
    const response = await axios.post(
      `${API_BASE_URL}/api/v1/generate-auth-token`,
      payload,
      {
        headers: {
          'Content-Type': 'application/json',
          'x-signature': signature,
          'x-timestamp': timestamp.toString()
        }
      }
    );

    console.log('Token generated:', response.data.data.token);
    console.log('Login link:', response.data.data.loginLink);
    return response.data;
  } catch (error: any) {
    console.error('Error:', error.response?.data || error.message);
    throw error;
  }
}

Python

import requests
# Import your signature generation function (see Overview)
from signature_utils import generate_signature
import time

API_BASE_URL = 'https://wdcf.xerve.online'
CLIENT_SECRET = 'your-secret-key'

def generate_auth_token():
    timestamp = int(time.time())
    payload = {
        "clientId": "CLIENT_001",
        "username": "testuser001",
        "displayName": "Client One",
        "ipAddress": "192.168.1.100",
        "expiration": 5
    }

    # Generate signature (see Overview for implementation)
    signature = generate_signature(
        method="POST",
        path="/api/v1/generate-auth-token",
        payload=payload,
        secret=CLIENT_SECRET,
        timestamp=timestamp
    )

    headers = {
        "Content-Type": "application/json",
        "x-signature": signature,
        "x-timestamp": str(timestamp)
    }

    response = requests.post(
        f"{API_BASE_URL}/api/v1/generate-auth-token",
        json=payload,
        headers=headers
    )

    response.raise_for_status()
    data = response.json()
    print(f"Token: {data['data']['token']}")
    print(f"Login link: {data['data']['loginLink']}")
    return data

if __name__ == "__main__":
    generate_auth_token()

Important Notes

  1. Token Expiration: Tokens are single-use and expire after the specified duration (default: 2 minutes, max: 24 hours)
  2. Signature Timestamp: The timestamp must be within 5 minutes of the server time or the request will be rejected
  3. Idempotency: Each call generates a new unique token. Previously generated tokens remain valid until their expiration
  4. User Linking: The clientId is the primary identifier for linking your external users to internal user accounts
  5. Login Flow: Redirect users to the loginLink URL to authenticate them automatically. The token will be validated and consumed upon successful login.
  6. IP Address: The ipAddress is stored for audit purposes and security tracking

Error Handling

Error CodePossible CausesResolution
400Missing/invalid required fieldsCheck validation errors in response
401Invalid signature or expired timestampVerify signature generation logic and ensure timestamp is current
500Database error or wallet initialization failureCheck server logs, retry request

Security Considerations

  1. Keep CLIENT_SECRET secure: Never expose it in client-side code or version control
  2. Use HTTPS: Always use HTTPS in production to prevent signature interception
  3. Token expiration: Use short expiration times (2-5 minutes) for better security
  4. IP validation: Consider validating the IP address matches expected ranges