1House Global API Documentation

Authentication

Learn how to authenticate with the 1House Global API

The 1House Global API uses a two-layer authentication system with platform-based access control.

Two-Layer Security

All API requests require two layers: API Key (platform level) and JWT token (user level) for secure access.

Authentication Layers

The 1House Global API uses a two-layer authentication system:

Layer 1: API Key (Platform Level)

All API requests require an X-API-Key header:

X-API-Key: your-api-key-here

Purpose: Identifies which application is making the request (Mobile app, Web platform, CRM, etc.)

Layer 2: JWT Token (User Level)

Most endpoints also require a JWT token:

Authorization: Bearer your-jwt-token-here

Purpose: Identifies which user is making the request

Getting Your API Keys

API keys are managed by administrators. Contact your administrator to get API keys for both environments (development and production).

Available API Key Types:

  • Mobile App - For mobile applications
  • Live Platform - For web applications
  • CRM - For internal CRM systems
  • Third Party - For external integrations
  • Admin - For administrative access

Each key type has different rate limits and permissions.

You'll need separate API keys for development and production environments. Request both from your administrator.

Platform Types

Platform Parameter Required

All sign-in requests must include a platform parameter to specify which 1House platform you're accessing.

Supported platforms: See Platform Types for the full list of valid values, SKU requirements, and access windows.

User Authentication Flow

Sign In

Authenticate existing user (External Backoffice authentication):

POST /v1/auth/signin
X-API-Key: your-api-key
Content-Type: application/json

External Backoffice Authentication

Sign-in authenticates against the External Backoffice backend and validates platform-specific service access.

{
  "email": "user@example.com",
  "password": "password123",
  "platform": "app",            // REQUIRED: see Platform Types
  "device": "mobile",            // Optional: mobile | web | tablet
  "deviceId": "device-uuid-123"  // Optional: unique device identifier
}

Required Fields:

  • email - User email address
  • password - User password
  • platform - Platform type (validates service access)

Optional Fields:

  • device - Device type (default: web)
  • deviceId - Unique device identifier
{
  "success": true,
  "status": 200,
  "message": "Signed in to Mobile App successfully",
  "data": {
    "user": {
      "id": "user_123",
      "email": "user@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "role": "user",
      "customerId": "33"
    },
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "sessionId": "def-456-ghi-789",     // MongoDB session UUID
    "platform": "app",
    "platformName": "Mobile App",
    "expiration": "2025-12-31T23:59:59.000Z",  // External Backoffice service expiration
    "backofficeAccessToken": "eyJhbGciOiJIUzI1NiIs...",  // Token for direct backoffice API calls
    "backofficeRefreshToken": "eyJhbGciOiJIUzI1NiIs..."  // Refresh token for backoffice
  },
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1"
  }
}

Backoffice Tokens: The backofficeAccessToken and backofficeRefreshToken are returned from the 1houseglobal.dev backoffice. Use the backofficeAccessToken with the X-Backoffice-Token header for endpoints like /user/get and /user/customer-status:

X-Backoffice-Token: {backofficeAccessToken}
{
  "success": false,
  "status": 403,
  "message": "No access to Mobile App. Missing services: 34, 35",
  "error": "No access to Mobile App. Missing services: 34, 35",
  "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1",
    "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Error UUID: Use the errorId for quick error lookup and support requests.

Try it out:

Sign In (Single Sign-On)

Authenticate by customer ID or user ID (no password). Returns the same payload as normal sign-in (user, JWT tokens, session, backoffice tokens).

Supported platforms (SSO)

See Platform Types for the full list. Only livestream is used for redirect-based SSO: use platform=livestream to get the redirect URL or 302 redirect.

Ways to call SSO:

MethodUse case
GET with query paramsSingle URL (link or redirect). When platform=livestream, the server responds with 302 redirect to the livestream app with a single JWT containing all data.
POST with JSON bodyAPI clients. When platform=livestream, the JSON response includes redirectUrl (URL with JWT) so the client can redirect the user.

Required backoffice tokens

Every request must include the backoffice accessToken (bearer) and refreshToken. They are echoed back as backofficeAccessToken and backofficeRefreshToken for backoffice API calls (e.g. X-Backoffice-Token).

Livestream redirect: With platform=livestream, the backend returns a 302 to {LIVESTREAM_SSO_REDIRECT_URL}/sso?token={jwt}. The JWT (5 min) holds user, tokens, and session data; the livestream app verifies it with the shared JWT secret. Set LIVESTREAM_SSO_REDIRECT_URL on the auth service.

  • GET – Query params (table below). platform=livestream returns 302 to livestream app; otherwise 200 JSON.
  • POST – JSON body: customerId or userId, accessToken, refreshToken (required); platform, device, deviceId (optional). 200 JSON; if platform=livestream, response includes data.redirectUrl.

Query parameters (GET /v1/auth/signin-sso):

ParameterTypeRequiredDescription
customerIdstringOne of with userIdCustomer ID from backoffice
userIdstringOne of with customerIdUser ID (MongoDB ObjectId)
accessTokenstringYesBackoffice bearer token
refreshTokenstringYesBackoffice refresh token
platformstringNoUse livestream for redirect; default app. See Platform Types.
devicestringNoe.g. web
deviceIdstringNoDevice identifier
noRedirectstringNoSet to 1 or true to return 200 JSON with data.redirectUrl instead of 302 redirect. Use when testing (e.g. in api-docs) so the redirect URL is shown instead of following the redirect.

Example GET URL: GET /v1/auth/signin-sso?customerId=33&accessToken=...&refreshToken=...&platform=livestream

For testing in api-docs, add &noRedirect=1 so the response is 200 JSON with data.redirectUrl instead of a 302 redirect.

{
  "customerId": "33",
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
  "platform": "livestream",
  "device": "web",
  "deviceId": "device-uuid-123"
}

Use userId (MongoDB ObjectId) instead of customerId if preferred. For GET, pass the same fields as query parameters (see table above).

GET with platform=livestream: 302 redirect. No JSON body. Location header is {LIVESTREAM_SSO_REDIRECT_URL}/sso?token={jwt}. The JWT payload (decode with auth service JWT secret) contains: type: "sso-redirect", userId, sessionId, user, accessToken, refreshToken, backofficeAccessToken, backofficeRefreshToken. JWT expiry: 5 minutes. With noRedirect=1: returns 200 with data.redirectUrl (same URL) so you can test without following the redirect.

200 JSON (POST, or GET):

{
  "success": true,
  "status": 200,
  "message": "Signed in successfully",
  "data": {
    "user": { "id": "...", "customerId": "33", "email": "...", "firstName": "...", "lastName": "...", "role": "user", "permissions": [] },
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "sessionId": "def-456-ghi-789",
    "backofficeAccessToken": "eyJhbGciOiJIUzI1NiIs...",
    "backofficeRefreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "redirectUrl": "https://1house.tv/sso?token=eyJhbGciOiJIUzI1NiIs..."
  },
  "meta": { "timestamp": "...", "version": "v1" }
}

When platform=livestream, data.redirectUrl is the livestream base URL with ?token={jwt} (e.g. https://www.1h.tv/sso?token=...).

Try it out (POST):

Try it out (GET with noRedirect=1 — returns redirect URL in JSON instead of 302):

Use Access Token

Include the access token in subsequent requests:

GET /v1/user/profile
X-API-Key: your-api-key
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

The session created during sign-in is tracked in MongoDB and includes:

  • Platform and device information
  • Session expiration (7 days)
  • Activity tracking
  • Automatic cleanup after expiration

Refresh Token

Token Expiration

Access tokens expire after 15 minutes. Implement automatic token refresh to maintain seamless user experience.

Access tokens expire after 15 minutes. Use the refresh token to get a new one:

# Development
POST https://api-gateway.dev.1houseglobalservices.com/v1/auth/refresh-token
X-API-Key: your-development-api-key
Content-Type: application/json

# Production
POST https://api-gateway.prod.1houseglobalservices.com/v1/auth/refresh-token
X-API-Key: your-production-api-key
Content-Type: application/json
{
  "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}

Response:

{
  "success": true,
  "status": 200,
  "message": "Token refreshed successfully",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
  },
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1"
  }
}

Token Lifecycle

Token TypeExpirationPurposeStorage
Access Token15 minutesAPI requestsMemory/localStorage
Refresh Token7 daysRenew access tokenSecure storage

Best Practices

**Store tokens securely

  • Use httpOnly cookies for web apps
  • Use secure storage for mobile apps
  • Never expose tokens in URLs

**Handle token expiration

// Example: Auto-refresh on 401
if (response.status === 401) {
  const newToken = await refreshAccessToken();
  // Retry original request with new token
}

**Clear tokens on logout

localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');

Session Management

MongoDB Sessions

All authentication creates persistent sessions in MongoDB with platform, device, and activity tracking.

Session Properties

  • sessionId - Unique UUID for the session
  • platform - Which platform (see Platform Types)
  • device - Device type (mobile, web, tablet)
  • isActive - Session status
  • expiresAt - Auto-expiration (7 days)
  • lastActivityAt - Last request timestamp

Get User

Retrieve user information from the backoffice system. Can accept either a customerId (string) or MongoDB ObjectId.

POST /v1/user/get
X-API-Key: your-api-key
Authorization: Bearer your-access-token
X-Backoffice-Token: backoffice-access-token
Content-Type: application/json

Backoffice Integration

This endpoint calls the external backoffice API to retrieve user data.

Required Headers:

  • Authorization: Bearer token for backend authentication (your JWT)
  • X-Backoffice-Token: The backofficeAccessToken returned from sign-in (used for backoffice API calls)

With customerId (string):

{
  "customerId": "33"
}

With userId (MongoDB ObjectId):

{
  "userId": "507f1f77bcf86cd799439011"
}

Snake case is also supported:

{
  "customer_id": "33"
}

or

{
  "user_id": "507f1f77bcf86cd799439011"
}

Note: If a MongoDB ObjectId is provided via userId or user_id, the system will automatically query MongoDB to find the user and retrieve their customerId before calling the backoffice API.

{
  "success": true,
  "status": 200,
  "message": "User info retrieved successfully",
  "data": {
    "user": {
      "id": 33,
      "wordpress_user_id": null,
      "username": "dahmeyon",
      "email": "dahmeyon@younivision.com",
      "is_super_admin": 0,
      "is_sub_admin": 0,
      "sponsor": 6,
      "active": 1,
      "customer": 0,
      "rank_id": 1,
      "unilevel_rank_id": 1,
      "is_vested_binary": 0,
      "is_vested_unilevel": 0,
      "vested_binary_rank": null,
      "vested_unilevel_rank": null,
      "package_id": 0,
      "block_type": null,
      "is_turn_on_email": 1,
      "public_key": null,
      "effective_start_date": null,
      "effective_until": null,
      "breakage_share": 0,
      "created_at": "2025-12-08T17:29:03.000000Z",
      "updated_at": "2025-12-08T17:29:03.000000Z",
      "email_verified_at": null,
      "remember_token": null,
      "google2fa_secret": "0",
      "google2fa_secret_url": "0",
      "advanced_reporting": 0
    },
    "services": []
  },
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1"
  }
}

Try it out:

Get Customer Status

Retrieve customer status from the 1houseglobal.dev backoffice. This endpoint provides a structured response with customer status, active state, and associated services.

POST /v1/user/customer-status
X-API-Key: your-api-key
Authorization: Bearer your-access-token
X-Backoffice-Token: backoffice-access-token
Content-Type: application/json

Flexible Identifier & Required Headers

This endpoint accepts either a customerId (backoffice ID) or userId (MongoDB ObjectId). If a MongoDB ObjectId is provided, the system automatically looks up the user's customerId before calling the backoffice.

Required Headers:

  • Authorization: Bearer token for backend authentication (your JWT)
  • X-Backoffice-Token: The backofficeAccessToken returned from sign-in (used for backoffice API calls)

With customerId:

{
  "customerId": "33"
}

With userId (MongoDB ObjectId):

{
  "userId": "65a1b2c3d4e5f6789abcdef0"
}

Snake case is also supported:

{
  "customer_id": "33"
}

or

{
  "user_id": "65a1b2c3d4e5f6789abcdef0"
}
{
  "success": true,
  "status": 200,
  "message": "Customer status retrieved successfully",
  "data": {
    "customerId": "33",
    "userId": "65a1b2c3d4e5f6789abcdef0",
    "status": {
      "active": true,
      "email": "user@example.com",
      "username": "johndoe",
      "createdAt": "2025-01-15T10:30:00.000Z",
      "lastLogin": "2025-01-21T08:45:00.000Z"
    },
    "services": [
      {
        "id": 34,
        "name": "Mobile App Access",
        "active": true
      },
      {
        "id": 35,
        "name": "Live Platform Access",
        "active": true
      }
    ],
    "raw": {
      "user": { /* full backoffice user object */ },
      "services": [ /* full services array */ ]
    }
  },
  "meta": {
    "timestamp": "2025-01-21T12:00:00.000Z",
    "version": "v1"
  }
}

User not found:

{
  "success": false,
  "status": 404,
  "message": "User not found in MongoDB",
  "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

User has no customerId:

{
  "success": false,
  "status": 400,
  "message": "User does not have a customerId linked to backoffice",
  "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Try it out:

Sign Out

Invalidate sessions with granular control. For platform users (users with customerId), this also signs them out from the external backoffice system.

POST /v1/auth/signout
X-API-Key: your-api-key
Authorization: Bearer your-access-token
Content-Type: application/json

Backoffice Integration

For platform users (users with a customerId), signing out will also automatically sign them out from the external backoffice system. The bearer token is forwarded to the backoffice for authentication.

Sign out from all devices and platforms:

{}

Response:

{
  "success": true,
  "status": 200,
  "message": "Signed out successfully",
  "data": {
    "message": "Signed out successfully",
    "device": null,
    "platform": null
  },
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1"
  }
}

Sign out from specific platform only:

{
  "platform": "app"
}

Deactivates all "app" sessions, keeps "livestream", "scanners", "web", and "backoffice" sessions active.

Sign out from specific device and platform:

{
  "device": "mobile",
  "platform": "app"
}

Deactivates only mobile+app sessions, keeps other combinations active.

Sign out a specific user by customerId or MongoDB ObjectId:

{
  "customerId": "33"
}

or

{
  "customerId": "507f1f77bcf86cd799439011"
}

Note: If a MongoDB ObjectId is provided, the system will automatically query MongoDB to find the user before signing them out.

Try it out:

Admin User Management

Admin user management endpoints live under /v1/admin/auth/users. They require admin authentication.

Base Path: /v1/admin/auth/users

List Users (Admin)

GET /v1/admin/auth/users

Query Parameters:

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberResults per page (default: 20)
searchstringSearch by name or email
rolestringFilter by role: user, educator, admin

Create User (Admin)

Create a new user (e.g. for educators or backoffice mapping).

POST /v1/admin/auth/users

Request Body:

{
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "password": "SecurePass123!",
  "role": "educator",
  "customerId": "42",
  "username": "janedoe",
  "permissions": ["educator"],
  "phone": "+1234567890",
  "profileImage": "https://cdn.1houseglobal.com/avatar.jpg"
}

Required Fields:

  • firstName - First name (2–50 characters)
  • lastName - Last name (2–50 characters)
  • email - Email address
  • password - Password (min 8 characters)

Optional Fields:

  • role - One of user, admin, moderator, educator (default: user). Often used to derive permissions.
  • username - Display/login username. If omitted, a unique username is auto-generated from the email.
  • customerId - Backoffice customer ID; links this user to the external backoffice (mapped user).
  • permissions - Array of permission strings (e.g. ["educator"], ["admin"]). Can be set from role.
  • phone - E.164 format
  • profileImage - URL

Update User (Admin)

Update an existing user. Use this to map a user to the backoffice (customerId) or change profile/role.

PUT /v1/admin/auth/users/:userId

Request Body (all optional):

{
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "customerId": "42",
  "role": "educator",
  "profileImage": "https://cdn.1houseglobal.com/avatar.jpg",
  "educator_title": "Senior Educator",
  "educator_bio": "Trading and education.",
  "skills": ["Trading", "Education"]
}

Mapping to backoffice: Set customerId (and optionally email) to link a user to the external backoffice. Users with a customerId are considered "mapped"; sign-in and profile can use backoffice data.

Optional educator fields: educator_title, educator_bio, banner_image, specialty, skills, socials, etc. See User Profile and Educators for full lists.

Password Reset

Request Reset

POST /v1/auth/forgot-password
{
  "email": "user@example.com"
}

Reset Password

POST /v1/auth/reset-password
{
  "token": "reset-token-from-email",
  "newPassword": "NewSecurePass123!"
}

Email Verification

Verify Email

POST /v1/auth/verify-email
{
  "token": "verification-token-from-email"
}

Resend Verification

POST /v1/auth/resend-verification
X-API-Key: your-api-key
Authorization: Bearer your-access-token

Security Features

Rate Limiting

  • Per API key
  • Per endpoint
  • Configurable limits by tier

Token Blacklisting

  • Logout invalidates tokens
  • Tokens cannot be reused
  • Stored in Redis for fast lookup

Password Requirements

  • Minimum 8 characters
  • Must include uppercase letter
  • Must include lowercase letter
  • Must include number
  • Must include special character

Failed Login Protection

  • Account locked after 5 failed attempts
  • 15-minute lockout period
  • Email notification on lockout

Error Handling

4xx forwarding

The API gateway forwards 4xx status codes and error messages from the auth service. Validation and auth errors (e.g. duplicate email, invalid credentials) are returned with the correct status (400, 401, 403, 404) instead of being converted to 500.

Error UUIDs

All errors include a unique errorId (UUID) for quick reference and support lookup. The error is logged centrally with complete context.

Error Response Format

{
  "success": false,
  "status": 403,
  "message": "No access to Mobile App. Missing services: 34, 35",
  "error": "No access to Mobile App. Missing services: 34, 35",
  "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "meta": {
    "timestamp": "2025-10-21T12:00:00.000Z",
    "version": "v1",
    "errorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Using Error UUIDs:

  • Include errorId in support requests for quick debugging
  • Error details stored in centralized error-log-service
  • Full request context, stack traces, and user info available
  • Automatic sensitive data sanitization

Error Codes

Status CodeErrorDescription
400Bad RequestInvalid platform or missing required fields
401UnauthorizedMissing or invalid API key
401Invalid TokenJWT token is invalid or expired
401Token ExpiredAccess token has expired, refresh it
403ForbiddenNo access to platform (missing required SKU) or account inactive
429Too Many RequestsRate limit exceeded

Platform Access Errors

PlatformErrorReason
appMissing services: 34, 35User doesn't have both required services
livestreamNo access to Live Platform. A valid subscription (SKU) is required.User has no required SKU for livestream
appNo access to Mobile App. A valid subscription (SKU) is required.User has no required SKU for app
scannersNo access to Scanners. A valid subscription (SKU) is required.User has no required SKU for scanners (when SKUs defined)

Code Examples

// Configure environment URLs and API keys
const DEV_API_URL = 'https://api-gateway.dev.1houseglobalservices.com';
const PROD_API_URL = 'https://api-gateway.prod.1houseglobalservices.com';

const DEV_API_KEY = 'your-development-api-key';
const PROD_API_KEY = 'your-production-api-key';

// Use appropriate environment
const apiUrl = process.env.NODE_ENV === 'production' ? PROD_API_URL : DEV_API_URL;
const apiKey = process.env.NODE_ENV === 'production' ? PROD_API_KEY : DEV_API_KEY;

// Sign in with platform
const response = await fetch(`${apiUrl}/v1/auth/signin`, {
  method: 'POST',
  headers: {
    'X-API-Key': apiKey,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'password123',
    platform: 'app',          // REQUIRED: see Platform Types
    device: 'mobile',          // Optional
    deviceId: 'device-uuid'    // Optional
  })
});

if (!response.ok) {
  const error = await response.json();
  console.error(`Error ${error.errorId}: ${error.message}`);
  // Include errorId in support requests
  throw new Error(error.message);
}

const { data } = await response.json();
const { accessToken, refreshToken, sessionId, platform, platformName } = data;

// Store tokens and session info
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
localStorage.setItem('sessionId', sessionId);
localStorage.setItem('platform', platform);

// Make authenticated request
const profileResponse = await fetch(`${apiUrl}/v1/user/profile`, {
  headers: {
    'X-API-Key': apiKey,
    'Authorization': `Bearer ${accessToken}`
  }
});
import requests
import os

# Configure environment URLs and API keys
DEV_API_URL = 'https://api-gateway.dev.1houseglobalservices.com'
PROD_API_URL = 'https://api-gateway.prod.1houseglobalservices.com'

DEV_API_KEY = 'your-development-api-key'
PROD_API_KEY = 'your-production-api-key'

# Use appropriate environment
api_url = PROD_API_URL if os.getenv('ENVIRONMENT') == 'production' else DEV_API_URL
api_key = PROD_API_KEY if os.getenv('ENVIRONMENT') == 'production' else DEV_API_KEY

# Sign in with platform (current backoffice does not support sign-up)
response = requests.post(
    f'{api_url}/v1/auth/signin',
    headers={
        'X-API-Key': api_key,
        'Content-Type': 'application/json'
    },
    json={
        'email': 'user@example.com',
        'password': 'SecurePass123!',
        'platform': 'app',      # REQUIRED
        'device': 'mobile',     # Optional
        'deviceId': 'device-uuid'  # Optional
    }
)

data = response.json()
access_token = data['data']['accessToken']
refresh_token = data['data']['refreshToken']

# Make authenticated request
profile = requests.get(
    f'{api_url}/v1/user/profile',
    headers={
        'X-API-Key': api_key,
        'Authorization': f'Bearer {access_token}'
    }
)
# Development - Sign in (current backoffice does not support sign-up)
curl -X POST https://api-gateway.dev.1houseglobalservices.com/v1/auth/signin \
  -H "X-API-Key: your-development-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123",
    "platform": "app"
  }'

# Production - Sign in
curl -X POST https://api-gateway.prod.1houseglobalservices.com/v1/auth/signin \
  -H "X-API-Key: your-production-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePass123!",
    "platform": "app"
  }'

Next Steps