Documentation

API reference, authentication, and integration guides for the FiveM licensing platform

Getting Started

Quick Start Guide

Integrate license verification into your FiveM resource in minutes. Your server calls the public verify endpoint using the 6-digit file code from your dashboard. No API key is required for in-game verification.

LUA Example
-- Add to server.lua — replace YOUR_FILE_CODE with your 6-digit code

PerformHttpRequest("http://vf1.host/api/verify/YOUR_FILE_CODE", function (err, text, head)
    if string.match(text, "Sorry,") then
        print("^1[License] Invalid: " .. text)
        StopResource(GetCurrentResourceName())
    else
        print("^2[License] Verified successfully!")
        -- Your script code here
    end
end, 'GET', '')

Create Your First File

Create a file in the dashboard or via the REST API. Each file gets a unique 6-digit code used in verification.

TEXT Example
Dashboard:
1. Log in at http://vf1.host
2. Go to Dashboard > Files
3. Click "Add File" and enter a name
4. Copy the 6-digit File Code

API (requires active subscription + API key):
POST http://vf1.host/api/file
Header: X-Api-Key: YOUR_API_KEY
Body: { "name": "My Script" }

Response: { "success": true, "file": { "id": 1, "file_code": "123456", ... } }

Activate a License

Bind a server IP to your file. The verify endpoint checks the requesting server IP against active licenses.

TEXT Example
Dashboard:
1. Go to Dashboard > License
2. Click "Add License"
3. Select your file, enter server IP, optional Discord ID & expiry

API:
POST http://vf1.host/api/license
Header: X-Api-Key: YOUR_API_KEY
Body: {
  "fileId": "123456",
  "ipAddress": "192.168.1.100",
  "discordId": "963091911768440903",
  "expiresAt": "2026-12-31T23:59:59.000Z"
}

API Authentication

Your API Key

Each account has a unique permanent API key generated once at registration. Find it in Settings > Account > API Key. Use the Copy button to copy it. Never share your API key publicly.

TEXT Example
Where to find it:
http://vf1.host/settings → Account card → API Key → Copy

Properties:
• Generated once per account (unique & permanent)
• Hidden in the UI — use Copy to get the full value
• Tied to your account — all actions run as you

Authentication Headers

Send your API key on every REST API request. Browser sessions (logged-in dashboard) also work without the header. All management endpoints require an active subscription.

BASH Example
# Option 1 — X-Api-Key header (recommended)
curl -H "X-Api-Key: YOUR_API_KEY" http://vf1.host/api/files

# Option 2 — Bearer token
curl -H "Authorization: Bearer YOUR_API_KEY" http://vf1.host/api/files

# With JSON body
curl -X POST http://vf1.host/api/file \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"My Resource"}'

Subscription Requirement

REST API access is restricted to accounts with an active subscription — the same rule as the License page in the dashboard. Without a subscription you receive HTTP 403.

ALL /api/* (management routes) API Key + Subscription
JSON Example
// 401 — Missing or invalid API key / not logged in
{ "error": "Unauthorized" }
{ "error": "Invalid API key" }

// 403 — No active subscription
{ "error": "No active subscription. Contact the administrator to get access." }

// 200 — Success
{ "success": true, ... }

Files API

List Files

Returns all files owned by the authenticated user.

GET /api/files Required
BASH Example
curl -H "X-Api-Key: YOUR_API_KEY" http://vf1.host/api/files

# Response
{
  "success": true,
  "files": [
    { "id": 1, "name": "My Script", "file_code": "123456", "created_at": "..." }
  ]
}

Create File

Creates a new file and returns a unique 6-digit file code.

POST /api/file Required
BASH Example
curl -X POST http://vf1.host/api/file \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My FiveM Script"}'

# Response
{ "success": true, "file": { "id": 1, "name": "My FiveM Script", "file_code": "482910" } }

Delete File

Deletes a file by numeric ID. Files with active licenses cannot be deleted — remove licenses first.

DELETE /api/file/:id Required
BASH Example
curl -X DELETE http://vf1.host/api/file/1 \
  -H "X-Api-Key: YOUR_API_KEY"

# Response
{ "success": true, "message": "File deleted successfully" }

Licenses API

List Licenses

Returns all licenses for the authenticated user, including linked file info.

GET /api/licenses Required
BASH Example
curl -H "X-Api-Key: YOUR_API_KEY" http://vf1.host/api/licenses

# Response
{
  "success": true,
  "licenses": [
    {
      "id": 1,
      "ip_address": "192.168.1.100",
      "license_key": "...",
      "file_code": "123456",
      "is_active": 1,
      "expires_at": null
    }
  ]
}

Create License

Activates a license for a file code and server IP. fileId is the 6-digit file code (not the numeric database ID).

POST /api/license Required
BASH Example
curl -X POST http://vf1.host/api/license \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fileId": "123456",
    "ipAddress": "192.168.1.100",
    "discordId": "963091911768440903",
    "expiresAt": "2026-12-31T23:59:59.000Z"
  }'

# Required: fileId, ipAddress
# Optional: discordId, expiresAt (ISO 8601)

Get / Update / Delete License

Manage individual licenses by numeric license ID (from list response).

PUT /api/license/:id Required
BASH Example
# Get license
curl -H "X-Api-Key: YOUR_API_KEY" http://vf1.host/api/license/1

# Update license
curl -X PUT http://vf1.host/api/license/1 \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ipAddress": "10.0.0.50",
    "discordId": "963091911768440903",
    "expiresAt": "2027-01-01T00:00:00.000Z",
    "isActive": true
  }'

# Delete license
curl -X DELETE http://vf1.host/api/license/1 \
  -H "X-Api-Key: YOUR_API_KEY"

Scripts API

List Scripts

Returns all scripts with their server/client files.

GET /api/scripts Required
BASH Example
curl -H "X-Api-Key: YOUR_API_KEY" http://vf1.host/api/scripts

# Response
{
  "success": true,
  "scripts": [
    {
      "id": 1,
      "name": "My Resource",
      "verification_code": "123456",
      "files": [
        { "id": 1, "file_path": "server/main.lua", "file_type": "server" }
      ]
    }
  ]
}

Create Script

Creates a script container. Optionally link a dashboard file by numeric file ID for verification code binding.

POST /api/script Required
BASH Example
curl -X POST http://vf1.host/api/script \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "My Resource", "fileId": 1 }'

# fileId is optional (numeric ID from /api/files)

Script Files

Add, update, or delete server/client script files within a script. POST upserts — creates if new, updates if path exists.

POST /api/script/:id/file Required
BASH Example
# Add or update script file
curl -X POST http://vf1.host/api/script/1/file \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filePath": "server/main.lua",
    "fileType": "server",
    "code": "print(\"Hello\")"
  }'

# fileType: "server" or "client"

# Delete script file
curl -X DELETE http://vf1.host/api/script/file/5 \
  -H "X-Api-Key: YOUR_API_KEY"

# Delete entire script
curl -X DELETE http://vf1.host/api/script/1 \
  -H "X-Api-Key: YOUR_API_KEY"

Upload & Obfuscate

Upload a .lua or .zip file for obfuscation. Requires multipart form data with the file field named "file".

POST /dashboard/upload Required
BASH Example
curl -X POST http://vf1.host/dashboard/upload \
  -H "X-Api-Key: YOUR_API_KEY" \
  -F "file=@./myscript.lua"

# Delete obfuscated upload
curl -X DELETE http://vf1.host/dashboard/file-upload/1 \
  -H "X-Api-Key: YOUR_API_KEY"

Public Verify API

License Verification (FiveM)

Public endpoint used by FiveM resources at runtime. No API key required. IP is detected automatically from the request.

GET /api/verify/:fileCode None (Public)
LUA Example
-- Used inside FiveM resources — no API key needed
PerformHttpRequest("http://vf1.host/api/verify/123456", function (err, text, head)
    if text == "Valid" then
        print("^2License OK")
    else
        print("^1" .. tostring(text))
    end
end, 'GET', '')

Verify + Fetch Script Code

When a path query parameter is provided and the license is valid, returns the obfuscated script code for that file path.

GET /api/verify/:fileCode?path= None (Public)
TEXT Example
GET http://vf1.host/api/verify/123456?path=server/main.lua

Valid license  → returns script code (text)
Invalid        → "Sorry, ..." error message

Responses:
• "Valid"                        — license active, no path requested
• "Sorry, Invalid license"       — file code not found
• "Sorry, IP address required"   — IP detection failed
• "Sorry, License not found..."  — no active license for this IP
• "Sorry, License expired"       — license expired

IP Detection

The verify endpoint reads the server IP from proxy headers or the direct connection. No manual IP parameter is needed.

TEXT Example
Detection order:
1. X-Forwarded-For (first IP, for Cloudflare/proxy)
2. X-Real-IP
3. Direct connection IP

The IP in your license must match the IP detected at runtime.

Integration Examples

Complete Server Example

Full FiveM server-side integration with automatic resource stop on invalid license.

LUA Example
-- server.lua
local FILE_CODE = "123456" -- Your 6-digit code from dashboard

Citizen.CreateThread(function()
    Citizen.Wait(2000)

    PerformHttpRequest("http://vf1.host/api/verify/" .. FILE_CODE, function (err, text, head)
        if err ~= 200 then
            print("^1[License] Connection error")
            return
        end

        if string.match(text, "Sorry,") then
            print("^1[License] " .. text)
            Citizen.Wait(2000)
            StopResource(GetCurrentResourceName())
        else
            print("^2[License] Verified — resource active")
        end
    end, 'GET', '')
end)

Node.js API Client

Example of managing licenses programmatically with your API key from Settings.

JAVASCRIPT Example
const API_KEY = 'YOUR_API_KEY';
const BASE = 'http://vf1.host';

async function api(method, path, body) {
  const res = await fetch(BASE + path, {
    method,
    headers: {
      'X-Api-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: body ? JSON.stringify(body) : undefined
  });
  return res.json();
}

// List files
const { files } = await api('GET', '/api/files');

// Create license
await api('POST', '/api/license', {
  fileId: files[0].file_code,
  ipAddress: '192.168.1.100'
});

Protected Events Pattern

Best practice: verify license on startup and gate all server events behind the verified flag.

LUA Example
local FILE_CODE = "123456"
local licenseVerified = false

Citizen.CreateThread(function()
    PerformHttpRequest("http://vf1.host/api/verify/" .. FILE_CODE, function (err, text)
        licenseVerified = (text == "Valid")
        if not licenseVerified then
            StopResource(GetCurrentResourceName())
        end
    end, 'GET', '')
end)

RegisterNetEvent('myresource:action')
AddEventHandler('myresource:action', function()
    if not licenseVerified then return end
    -- your logic here
end)

Discord Bot

Obfuscation Bot (!ob)

DM the bot with !ob and attach a .lua or .zip file. You must be logged in on the website with Discord linked. Requires an active subscription for full platform access.

TEXT Example
1. Log in at http://vf1.host with Discord linked
2. Join Discord: https://discord.gg/GMhpuwVtkP
3. DM the bot: !ob
4. Attach your .lua or .zip file
5. Receive obfuscated output

Supported: .lua files, .zip archives
Also available via API: POST http://vf1.host/dashboard/upload

Admin Bot Commands

Subscription management commands for authorized administrators only.

TEXT Example
!addob <discordId> [amount] <m|y|d>
  Grant subscription to a user by Discord ID
  Examples:
    !addob 963091911768440903 1 m   → 1 month
    !addob 963091911768440903 1 y   → 1 year
    !addob 963091911768440903 7 d   → 7 days

!unob <discordId>
  Remove subscription from a user

Troubleshooting

API Key Issues

Common problems when using the REST API with your API key.

TEXT Example
401 Unauthorized
→ Check X-Api-Key header is set correctly
→ Copy fresh key from Settings > Account > API Key

403 No active subscription
→ Contact admin for subscription
→ Verify subscription in Settings profile stats

Invalid API key
→ Key is account-specific — don't use the bot server key
→ Each user has their own unique key

License Verification Issues

Problems with the public /api/verify endpoint in FiveM.

TEXT Example
"Sorry, Invalid license"
→ Wrong file code — check Dashboard > Files

"Sorry, License not found or inactive"
→ Activate license for your server IP in Dashboard > License
→ IP must match exactly (check server IP)

"Sorry, License expired"
→ Update expiresAt via PUT /api/license/:id or dashboard

"Sorry, IP address required"
→ Proxy/header issue — contact support

Testing Checklist

Verify your full setup step by step.

LUA Example
-- 1. Test license verify (in FiveM server console)
PerformHttpRequest("http://vf1.host/api/verify/YOUR_CODE", function(e,t)
    print("[Test] Verify: " .. tostring(t))
end, 'GET', '')

-- 2. Test API key (terminal)
-- curl -H "X-Api-Key: KEY" http://vf1.host/api/files

-- Expected:
-- Verify → "Valid"
-- API    → { "success": true, "files": [...] }