Partner API Documentation

Complete guide for integrating with our Partner APIs

Signature Generation

Authentication Process

Partners must generate a signature for each request using the following steps:

  1. Concatenate: HTTP_METHOD + ENDPOINT_PATH + TIMESTAMP + REQUEST_BODY
  2. Apply HMAC-SHA256 with your Secret Key
  3. Send the result as X-SIGNATURE header

Create Users API

Signature Generation Examples

$apiSecret = "YOUR_SECRET_KEY"; $timestamp = time(); $method = "POST"; $endpoint = "/api/v1/partners/users"; $body = json_encode([ 'users' => [ ["email" => "[email protected]"], ["email" => "[email protected]"] ] ]); $signString = $method . $endpoint . $timestamp . $body; $signature = hash_hmac('sha256', $signString, $apiSecret);
import time, hmac, hashlib, json api_secret = "YOUR_SECRET_KEY" timestamp = str(int(time.time())) method = "POST" endpoint = "/api/v1/partners/users" body = json.dumps({ "users": [ {"email": "[email protected]"}, {"email": "[email protected]"} ] }, separators=(',', ':')) sign_string = method + endpoint + timestamp + body signature = hmac.new(api_secret.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; String apiSecret = "YOUR_SECRET_KEY"; long timestamp = System.currentTimeMillis() / 1000; String method = "POST"; String endpoint = "/api/v1/partners/users"; String body = "{\"users\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}"; String signString = method + endpoint + timestamp + body; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String signature = bytesToHex(sha256_HMAC.doFinal(signString.getBytes())); // Helper function to convert bytes to hex public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }

Endpoint

POST /api/v1/partners/users
Base URL: https://api.vifoxcollege.com

Headers

Header Type Required Example Value
Content-Type string Required application/json
Accept string Required application/json
X-API-KEY string Required YOUR_API_KEY
X-TIMESTAMP string Required TIMESTAMP
X-SIGNATURE string Required YOUR_SIGNATURE
X-TRANSACTION-ID string Required aron_7690567345

Request Body Structure

{ "users": [ { "email": "string (required)", "first_name": "string (optional)", "last_name": "string (optional)", "mobile": "string (optional)", "postal_code": "string (optional)", "address": "string (optional)", "username": "string (optional)", "referral_code": "string (optional)" } ] }

Example Request

{ "users": [ { "email": "[email protected]", "first_name": "Samanta", "last_name": "Smith", "mobile": "0901578978", "postal_code": "567-45", "address": "Paris", "username": "samanta_Smith", "referral_code": "jiskedobr" } ] }

Response

Success Response (New Users)

200 OK
{ "status": 200, "data": { "message": "Users have been created", "oldUsers": [] } }

Success Response (Some Existing Users)

200 OK
{ "status": 200, "data": { "message": "Users have been created", "oldUsers": [ "[email protected]" ] } }

Error Responses

405 Method Not Allowed
{ "message": "Invalid signature" }
406 Not Acceptable
{ "message": "Invalid partner" }
407 Proxy Authentication Required
{ "message": "Request expired" }
408 Request Timeout
{ "message": "Missing authentication headers" }
409 Conflict
{ "message": "Missing X-TRANSACTION-ID header" }
410 Gone
{ "message": "Duplicate transaction ID" }

Important Notes

  • Required field: email
  • Optional fields: first_name, last_name, mobile, postal_code, address, username, referral_code (can be null)
  • Bulk creation: You can send multiple users inside the users array
  • Signature: X-SIGNATURE should be generated according to your signing algorithm (HMAC-SHA256 based on API key + timestamp + payload)
  • X-TRANSACTION-ID: This header is required to prevent duplicate or replayed API requests. It must contain a unique transaction identifier for each request.
    • Format: {partner_name}_{unique_10_digit_number}
    • Example: X-TRANSACTION-ID: aron_7690567345
    • Rules:
      • Must be unique for each API call
      • Should include your registered partner name followed by an underscore (_) and a random 10-digit number
      • Once used successfully, the transaction ID cannot be reused
      • If the same transaction ID is sent again, the request will be rejected with a 410 (Duplicate Transaction) error

Add User Points API

Signature Generation Examples

$apiSecret = "YOUR_SECRET_KEY"; $timestamp = time(); $method = "POST"; $endpoint = "/api/v1/partners/points"; $body = json_encode([ 'users' => [ ["email" => "[email protected]", "point" => 200, "description" => "description", "external_transaction_id" => 8767], ["email" => "[email protected]", "point" => 333] ] ]); $signString = $method . $endpoint . $timestamp . $body; $signature = hash_hmac('sha256', $signString, $apiSecret);
import time, hmac, hashlib, json api_secret = "YOUR_SECRET_KEY" timestamp = str(int(time.time())) method = "POST" endpoint = "/api/v1/partners/points" body = json.dumps({ "users": [ {"email": "[email protected]", "point": 200, "description": "description", "external_transaction_id": 8767}, {"email": "[email protected]", "point": 333} ] }, separators=(',', ':')) sign_string = method + endpoint + timestamp + body signature = hmac.new(api_secret.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; String apiSecret = "YOUR_SECRET_KEY"; long timestamp = System.currentTimeMillis() / 1000; String method = "POST"; String endpoint = "/api/v1/partners/points"; String body = "{\"users\":[{\"email\":\"[email protected]\",\"point\":200, \"description\": \"description\", \"external_transaction_id\": 8767},{\"email\":\"[email protected]\",\"point\":333}]}"; String signString = method + endpoint + timestamp + body; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String signature = bytesToHex(sha256_HMAC.doFinal(signString.getBytes())); // Helper function to convert bytes to hex public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }

Endpoint

POST /api/v1/partners/points
Base URL: https://api.vifoxcollege.com

Headers

Header Type Required Example Value
Content-Type string Required application/json
Accept string Required application/json
X-API-KEY string Required YOUR_API_KEY
X-TIMESTAMP string Required 1756358967
X-SIGNATURE string Required YOUR_SIGNATURE
X-TRANSACTION-ID string Required aron_7690567345

Request Body Structure

{ "users": [ { "email": "string (required)", "point": "integer (required)", "description": "string (optional)", "external_transaction_id": "string (optional)" } ] }

Example Request

{ "users": [ { "email": "[email protected]", "point": 200, "description": "string (optional)", "external_transaction_id": 8789 }, { "email": "[email protected]", "point": 333, "description": "string (optional)" } ] }

Responses

Success Response (Mixed Results)

200 OK

Note: Each user has separate status and message

{ "status": 200, "data": [ { "status": 200, "email": "[email protected]", "external_transaction_id": null, "message": "success" }, { "status": 403, "email": "[email protected]", "external_transaction_id": 8789, "message": "Insufficient liquidity pool" }, { "status": 404, "email": "[email protected]", "external_transaction_id": null, "message": "Not registered user" }, { "status": 429, "email": "[email protected]", "external_transaction_id": null, "message": "Reached the limit of user's point" }, { "status": 403, "email": "[email protected]", "external_transaction_id": null, "message": "Insufficient user's point" } ] }

Response Status Codes (Per User)

Status Code Message Description
200 success Points successfully added to user
403 Insufficient liquidity pool Not enough points in the liquidity pool
403 Insufficient user's point User doesn't have enough points
404 Not registered user User email not found in the system
429 Reached the limit of user's point User has reached maximum point limit

Error Responses

405 Method Not Allowed
{ "message": "Invalid signature" }
406 Not Acceptable
{ "message": "Invalid partner" }
407 Proxy Authentication Required
{ "message": "Request expired" }
408 Request Timeout
{ "message": "Missing authentication headers" }
405 Method Not Allowed
{ "message": "Reached the limit of request" }
409 Conflict
{ "message": "Missing X-TRANSACTION-ID header" }
410 Gone
{ "message": "Duplicate transaction ID" }

Important Notes

  • Required fields: email, point
  • Optional fields: description, external_transaction_id
  • Bulk updates: You can send multiple users inside the users array
  • Individual responses: Each user has a separate status and message in the response
  • Success handling: Check individual user status codes to determine success/failure per user
  • Error types:
    • 404: User not found in system
    • 403: Insufficient liquidity pool or user points
    • 429: User reached maximum point limit
    • 200: Points successfully added
  • Signature: X-SIGNATURE should be generated according to your signing algorithm (HMAC-SHA256 based on API key + timestamp + payload)
  • X-TRANSACTION-ID: This header is required to prevent duplicate or replayed API requests. It must contain a unique transaction identifier for each request.
    • Format: {partner_name}_{unique_10_digit_number}
    • Example: X-TRANSACTION-ID: aron_7690567345
    • Rules:
      • Must be unique for each API call
      • Should include your registered partner name followed by an underscore (_) and a random 10-digit number
      • Once used successfully, the transaction ID cannot be reused
      • If the same transaction ID is sent again, the request will be rejected with a 410 (Duplicate Transaction) error

Get User Points and History API

Signature Generation Examples

$apiSecret = "YOUR_SECRET_KEY"; $timestamp = time(); $method = "POST"; $endpoint = "/api/v1/partners/user-points"; $signString = $method . $endpoint . $timestamp; $signature = hash_hmac('sha256', $signString, $apiSecret);
import time, hmac, hashlib, json api_secret = "YOUR_SECRET_KEY" timestamp = str(int(time.time())) method = "POST" endpoint = "/api/v1/partners/user-points" sign_string = method + endpoint + timestamp signature = hmac.new(api_secret.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; String apiSecret = "YOUR_SECRET_KEY"; long timestamp = System.currentTimeMillis() / 1000; String method = "POST"; String endpoint = "/api/v1/partners/user-points"; String signString = method + endpoint + timestamp; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String signature = bytesToHex(sha256_HMAC.doFinal(signString.getBytes())); // Helper function to convert bytes to hex public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }

Endpoint

POST /api/v1/partners/user-points
Base URL: https://api.vifoxcollege.com

Headers

Header Type Required Example Value
Content-Type string Required application/json
Accept string Required application/json
X-API-KEY string Required YOUR_API_KEY
X-TIMESTAMP string Required 1756358967
X-SIGNATURE string Required YOUR_SIGNATURE

Request Body

Body is optional. If you send users' emails, get point of user and if you do not send any email, you received list of user points that related to your account. Also you can send option : history, if you want history of user's points.

Request Body Structure

{ "users": ["array of email strings (optional)"], "option": "string - 'history' to include transaction history (optional)" }

Example 1: Get Specific Users Points (Without History)

Response 1:

200 OK
{ "status": 200, "data": [ { "status": 200, "point": "212", "email": "[email protected]", "message": "Valid User", "history": [] }, { "status": 200, "point": "0", "email": "[email protected]", "message": "Valid User", "history": [] }, { "status": 404, "point": null, "email": "[email protected]", "message": "Invalid User", "history": [] }, { "status": 404, "point": null, "email": "[email protected]", "message": "Invalid User", "history": [] } ] }

Example 2: Get Users Points with History

{ "users": [ "[email protected]", "[email protected]", "[email protected]", "[email protected]" ], "option": "history" }

Response 2:

200 OK
{ "status": 200, "data": [ { "status": 200, "point": "212", "email": "[email protected]", "message": "Valid User", "history": [ { "id": 102, "user_id": 90024, "point": 2, "reason": "partner", "type": "web_service", "description": "arongroup", "external_transaction_id": 8789, "item_id": 15, "active": true, "created_by": 0, "created_at": "2025-10-03T06:02:55.000000Z", "updated_at": "2025-10-03T06:02:55.000000Z", "deleted_at": null }, { "id": 103, "user_id": 90008, "point": -2, "reason": "user_partner", "type": "web_service", "description": null, "external_transaction_id": 8789, "item_id": 90024, "active": true, "created_by": 0, "created_at": "2025-10-03T06:02:55.000000Z", "updated_at": "2025-10-03T06:02:55.000000Z", "deleted_at": null }, { "id": 96, "user_id": 90024, "point": -50, "reason": "partner", "type": "web_service", "description": "arongroup", "external_transaction_id": 8788, "item_id": 15, "active": true, "created_by": 0, "created_at": "2025-09-22T08:48:04.000000Z", "updated_at": "2025-09-22T08:48:04.000000Z", "deleted_at": null }, { "id": 97, "user_id": 90008, "point": 50, "reason": "user_partner", "type": "web_service", "description": null, "external_transaction_id": 8788, "item_id": 90024, "active": true, "created_by": 0, "created_at": "2025-09-22T08:48:04.000000Z", "updated_at": "2025-09-22T08:48:04.000000Z", "deleted_at": null }, { "id": 94, "user_id": 90024, "point": -50, "reason": "partner", "type": "web_service", "description": "arongroup", "external_transaction_id": null, "item_id": 15, "active": true, "created_by": 0, "created_at": "2025-09-22T08:44:03.000000Z", "updated_at": "2025-09-22T08:44:03.000000Z", "deleted_at": null }, { "id": 95, "user_id": 90008, "point": 50, "reason": "user_partner", "type": "web_service", "description": null, "external_transaction_id": null, "item_id": 90024, "active": true, "created_by": 0, "created_at": "2025-09-22T08:44:03.000000Z", "updated_at": "2025-09-22T08:44:03.000000Z", "deleted_at": null }, { "id": 71, "user_id": 90024, "point": 300, "reason": "partner", "type": "web_service", "description": "arongroup", "external_transaction_id": null, "item_id": 15, "active": true, "created_by": 0, "created_at": "2025-09-18T10:14:40.000000Z", "updated_at": "2025-09-18T10:14:40.000000Z", "deleted_at": null }, { "id": 72, "user_id": 90008, "point": -300, "reason": "user_partner", "type": "web_service", "description": null, "external_transaction_id": null, "item_id": 90024, "active": true, "created_by": 0, "created_at": "2025-09-18T10:14:40.000000Z", "updated_at": "2025-09-18T10:14:40.000000Z", "deleted_at": null } ] }, { "status": 200, "point": "0", "email": "[email protected]", "message": "Valid User", "history": [] }, { "status": 404, "point": null, "email": "[email protected]", "message": "Invalid User", "history": [] }, { "status": 404, "point": null, "email": "[email protected]", "message": "Invalid User", "history": [] } ] }

Example 3: Get All Users Points (Without Body)

200 OK
{ "status": 200, "data": [ { "status": 200, "point": "1900", "email": "[email protected]", "message": "Valid User", "history": [] }, { "status": 200, "point": "212", "email": "[email protected]", "message": "Valid User", "history": [] } ] }

Example 4: No Data Available (Without Body)

404 Not Found
{ "status": 404, "data": { "status": 404, "message": "No data" } }

Error Responses

405
{ "message": "Invalid signature" }
405
{ "message": "Invalid partner" }
405
{ "message": "Request expired" }

Response Status Codes (Per User)

Status Code Message Description
200 Valid User User found and points retrieved successfully
404 Invalid User User email not found in the system

Important Notes

  • Optional fields: users (array of emails), option (set to "history" for transaction history)
  • Without body: Returns all users associated with your partner account
  • With specific users: Returns points for requested users only
  • History option: Include "option": "history" to get detailed transaction history
  • Individual user status: Each user in response has separate status (200 for valid, 404 for invalid) and message field
  • Invalid users: Non-existent users return status 404 with point = null and message "Invalid User"
  • No data scenario: If no users are associated with partner, returns 404 status with "No data" message
  • Signature: X-SIGNATURE should be generated according to your signing algorithm (HMAC-SHA256 based on API key + timestamp + payload)

Get User Info API

Signature Generation Examples

$apiSecret = "YOUR_SECRET_KEY"; $timestamp = time(); $method = "POST"; $endpoint = "/api/v1/partners/user-info"; $body = json_encode([ "email" => "[email protected]" ]); $signString = $method . $endpoint . $timestamp . $body; $signature = hash_hmac('sha256', $signString, $apiSecret);
import time, hmac, hashlib, json api_secret = "YOUR_SECRET_KEY" timestamp = str(int(time.time())) method = "POST" endpoint = "/api/v1/partners/user-info" body = json.dumps({ "email": "[email protected]" }) sign_string = method + endpoint + timestamp + body signature = hmac.new(api_secret.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; String apiSecret = "YOUR_SECRET_KEY"; long timestamp = System.currentTimeMillis() / 1000; String method = "POST"; String endpoint = "/api/v1/partners/user-info"; String body = "{\"email\":\"[email protected]\"}"; String signString = method + endpoint + timestamp + body; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String signature = bytesToHex(sha256_HMAC.doFinal(signString.getBytes())); // Helper function to convert bytes to hex public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }

Endpoint

POST /api/v1/partners/user-info
Base URL: https://api.vifoxcollege.com

Headers

Header Type Required Example Value
Content-Type string Required application/json
Accept string Required application/json
X-API-KEY string Required YOUR_API_KEY
X-TIMESTAMP string Required 1756358967
X-SIGNATURE string Required YOUR_SIGNATURE

Request Body Structure

{ "email": "string (required)" }

Example Request

{ "email": "[email protected]" }

Responses

Success Response

200 OK
{ "status": 200, "data": { "first_name": "Alice", "last_name": null, "email": "[email protected]", "point": "1800", "kyc_status": false, "parent": { "first_name": "Ellie", "last_name": "Pares", "email": "[email protected]", "referral_code": "ZoIBW1lu" } } }

User Not Found Response

404 Not Found
{ "status": 404, "data": { "message": "User not found" } }

Validation Error

422 Unprocessable Entity
{ "message": "The selected email is invalid.", "errors": { "email": [ "The selected email is invalid." ] } }

Error Responses

405 Method Not Allowed
{ "message": "Invalid signature" }
405 Method Not Allowed
{ "message": "Invalid partner" }
405 Method Not Allowed
{ "message": "Request expired" }

Important Notes

  • Required field: email
  • Response includes: User's personal information, current points, KYC status, and parent/referral information
  • Parent information: If user was referred by another user, parent object contains referrer details
  • Signature: X-SIGNATURE should be generated according to your signing algorithm (HMAC-SHA256 based on API key + timestamp + payload)

Get Remaining Liquidity Pool API

Signature Generation Examples

$apiSecret = "YOUR_SECRET_KEY"; $timestamp = time(); $method = "POST"; $endpoint = "/api/v1/partners/remaining-liquidity-pool"; $signString = $method . $endpoint . $timestamp; $signature = hash_hmac('sha256', $signString, $apiSecret);
import time, hmac, hashlib, json api_secret = "YOUR_SECRET_KEY" timestamp = str(int(time.time())) method = "POST" endpoint = "/api/v1/partners/remaining-liquidity-pool" sign_string = method + endpoint + timestamp signature = hmac.new(api_secret.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; String apiSecret = "YOUR_SECRET_KEY"; long timestamp = System.currentTimeMillis() / 1000; String method = "POST"; String endpoint = "/api/v1/partners/remaining-liquidity-pool"; String signString = method + endpoint + timestamp; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String signature = bytesToHex(sha256_HMAC.doFinal(signString.getBytes())); // Helper function to convert bytes to hex public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); }

Endpoint

POST /api/v1/partners/remaining-liquidity-pool
Base URL: https://api.vifoxcollege.com

Headers

Header Type Required Example Value
Content-Type string Required application/json
Accept string Required application/json
X-API-KEY string Required YOUR_API_KEY
X-TIMESTAMP string Required 1756358967
X-SIGNATURE string Required YOUR_SIGNATURE

Response

Success Response

200 OK
{ "status": 200, "data": { "liquidity_pool": "3700", "rate": 0.2 } }

Error Responses

405 Method Not Allowed
{ "message": "Invalid signature" }
405 Method Not Allowed
{ "message": "Invalid partner" }
405 Method Not Allowed
{ "message": "Request expired" }

Important Notes

  • No request body required: This is a simple POST request
  • Liquidity pool: Returns the remaining amount in the liquidity pool
  • Rate: Returns the current exchange rate
  • Signature: X-SIGNATURE should be generated according to your signing algorithm (HMAC-SHA256 based on API key + timestamp + payload)