Documentation

Orvex API Reference

Everything you need to integrate Orvex obfuscation into your workflow — from the web dashboard to the full REST API.

Introduction

OrvexSecurity compiles your Lua source code into a custom proprietary bytecode that runs inside a generated virtual machine (OrvexVM / VM L14). This documentation covers the REST API and the official @orvex/sdk Node.js package.

Base URL for all API requests:

text
https://www.orvex-sc.xyz

CLI Installation

Coming soon — The @orvex/cli package is currently in development and not yet available on npm. Use the web dashboard or the Node.js SDK in the meantime.

Once released, the CLI will let you protect scripts directly from your terminal — no browser needed after the first login. Requires Node.js 18+.

Windows

bash
npm install -g @orvex/cli

If orvex is not recognized after installation, the npm global bin directory is not in your PATH. Open PowerShell as administrator and run:

powershell
[System.Environment]::SetEnvironmentVariable(
  "PATH",
  [System.Environment]::GetEnvironmentVariable("PATH","User") + ";$env:APPDATA\npm",
  "User"
)

Close and reopen your terminal. orvex should now work.

Alternatively, add the path manually: Start → "Edit environment variables" → Path → New → paste %APPDATA%\npm → OK.

Linux / macOS

bash
npm install -g @orvex/cli

If orvex is not found, add the npm global bin to your shell profile:

bash
# Find the npm global prefix (works with all npm versions)
npm config get prefix

# The binaries are at <prefix>/bin — add it to your shell (bash example)
echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Verify
orvex

On macOS with Homebrew Node, the global bin is usually at /usr/local/bin which is already in PATH — no extra step needed.

First launch

bash
# Run without arguments to see the startup animation (first time only)
orvex

# Then authenticate:
orvex login

# Protect a script:
orvex obfuscate

# View connected devices:
orvex sessions

Note: The CLI requires an active internet connection for authentication and obfuscation. All processing is done server-side — obfuscation runs are deducted from your plan quota exactly like the web dashboard.

Quick Start

Install the SDK and protect your first script in under a minute.

bash
npm install @orvex/sdk
typescript
import { OrvexClient } from "@orvex/sdk"

const client = new OrvexClient({ apiKey: process.env.ORVEX_API_KEY })

const { output } = await client.obfuscate({
  code: `
    local function hello()
      print("Hello, World!")
    end
    hello()
  `,
  luaVersion: "fivem",
})

// output contains the protected Lua bytecode
console.log(output)

Authentication

All API requests require your API key in the Authorization header as a Bearer token. Find your key in the API Keys section of the dashboard.

bash
curl https://www.orvex-sc.xyz/api/obfuscate \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"code": "print(\"hello\")", "luaVersion": "fivem"}'

Note: API access requires a Pro plan or higher. Free users can obfuscate through the web dashboard only.

POST /api/obfuscate

Obfuscate a single Lua script. The request is processed synchronously — the protected output is returned directly in the response body. No polling required.

Request Body

ParameterTypeRequiredDescription
codestringYesRaw Lua source code to protect. Max 500 KB.
filenamestringNoOriginal filename — used in history. Defaults to "script.lua".
luaVersionstringNo"lua51" | "lua54" | "luajit" | "roblox" | "fivem" | "luau". Defaults to "lua51".
options.controlFlowbooleanNoFlatten control flow into a state machine dispatch loop. Default: true.
options.deadCodebooleanNoInject realistic dead-code blocks. Default: true.
options.vmInjectionbooleanNoCompile into OrvexVM (L14) with anti-tamper fingerprint. Requires Pro+. Default: false.
options.multiLayerbooleanNoDual-layer VM (L15): encrypted bytecode, implies vmInjection. Requires Premium+. Default: false.

Response

json
{
  "ok": true,
  "output": "-- [OrvexSecurity | Lua 5.1]\nlocal _unpack=unpack..."
}

Error response

json
{
  "error": "[L14:Parser] expected 'end', got ':' at 12:5"
}

Status codes

CodeMeaningDescription
400Bad RequestMissing code, or script exceeds the 500 KB limit.
401UnauthorizedMissing or invalid API key / session.
403ForbiddenOption requires a higher plan (vmInjection → Pro+, multiLayer → Premium+), or account banned.
422Unprocessable EntityLua syntax error — details in the error message with line:col.
429Too Many RequestsMonthly obfuscation quota reached. Upgrade your plan or wait for the next cycle.

POST /api/obfuscate/batch

Obfuscate up to 50 Lua files in a single request. Quota is deducted per file. Requires Pro plan or above.

Request Body

ParameterTypeRequiredDescription
filesarrayYesArray of { path: string, code: string } objects. Max 50 items, 500 KB per file.
luaVersionstringNoApplied to all files in the batch.
optionsobjectNoSame options as /api/obfuscate — applied to all files.

Response

json
{
  "results": [
    { "path": "server/main.lua",   "ok": true,  "output": "..." },
    { "path": "server/config.lua", "ok": false, "error": "[L14:Lexer] unexpected character..." }
  ]
}

cURL example

bash
curl https://www.orvex-sc.xyz/api/obfuscate/batch \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "luaVersion": "fivem",
    "files": [
      { "path": "server/main.lua",   "code": "print(\"main\")" },
      { "path": "server/config.lua", "code": "print(\"cfg\")"  }
    ]
  }'

GET /api/history

Returns your obfuscation history (metadata only — source code is never stored). History retention: 7 days (Free), 90 days (Pro), unlimited (Premium+).

Note: Accessing this endpoint via API key requires a Pro plan or higher. Session-authenticated requests (web dashboard) work on all plans.

Query Parameters

ParameterTypeRequiredDescription
offsetnumberNoNumber of entries to skip (for pagination). Defaults to 0.
limitnumberNoMax entries to return. Capped at 100. Defaults to 50.
bash
curl "https://www.orvex-sc.xyz/api/history?offset=0&limit=50" \
  -H "Authorization: Bearer your_api_key"
json
{
  "history": [
    {
      "id": "abc123",
      "filename": "main.lua",
      "size": 4096,
      "plan": "pro",
      "status": "success",
      "createdAt": "2026-06-24T14:32:00Z"
    }
  ],
  "total": 142,
  "offset": 0,
  "limit": 50,
  "retentionDays": 90
}

Rate Limits

Limits are applied per account (never per IP — shared CI runners are safe) over a sliding 60-second window. A batch request counts as one unit per file, so batching is neither penalized nor a loophole.

PlanRequests / minuteMax files / batch
Pro12050
Premium30050
Enterprise60050

Every response includes standard rate-limit headers so your client can pace itself:

text
X-RateLimit-Limit: 120        # your plan's per-minute budget
X-RateLimit-Remaining: 117    # units left in the current window
X-RateLimit-Reset: 1750792080 # unix time when the window resets

# On 429, additionally:
Retry-After: 12               # seconds to wait before retrying

When you exceed the limit the API returns 429 with a Retry-After header — honor it and the request will succeed on retry. Rate limits are independent from your monthly obfuscation quota.

Protection Levels

Every plan runs the full 16-layer pipeline (L0–L15 — identifier renaming, 8-mode string encryption, integer encoding, dead code, opaque predicates, and more). Paid plans additionally get denser junk bytecode and unlock the options below. All options can be combined.

controlFlowFree

Flattens all branches into a state-machine dispatch loop (L13). Breaks static decompilers.

deadCodeFree

Injects realistic dead code (24 factories — stdlib calls, math, pcall) with self-modifying seeds to obscure real logic.

vmInjectionPro

Compiles the script into OrvexVM (L14): custom bytecode with a per-build randomized instruction set, plus a Murmur3 anti-tamper fingerprint. Any file modification crashes at runtime.

multiLayerPremium

Dual-layer VM (L15): the bytecode program is additionally encrypted at rest with a position-dependent key stream and decrypted once at load — two independent barriers, near-native runtime speed.

Control Flow Obfuscation

All branching logic is compiled into a flat dispatch loop driven by an opaque state variable. The original structure becomes impossible to recover from the bytecode alone.

lua
-- Original source
for i = 1, 10 do
  print(i)
end

-- After OrvexSecurity (VM L14 bytecode, simplified representation)
-- The actual output is unreadable bytecode, not Lua source.
-- This is an illustration of the transformation applied internally.
local _state = 7
while _state ~= 40 do
  if _state == 7 then _state = 12
  elseif _state == 12 then
    -- loop body, encoded as opcode stream
    _state = 40
  end
end

Multi-Layer Pass

When multiLayer is enabled (Premium+), OrvexSecurity activates the dual-layer VM (L15): your script is compiled once into a per-build randomized-ISA bytecode program that is additionally encrypted at rest with a position-dependent key stream and decrypted a single time at load. Two independent barriers — custom instruction set + bytecode cipher — with single-pass execution, so runtime performance stays near-native.

Enabling multiLayer automatically implies vmInjection — you don't need to set both.

typescript
const { output } = await client.obfuscate({
  code: myScript,
  luaVersion: "fivem",
  options: {
    controlFlow: true,
    deadCode:    true,
    vmInjection: true,   // Pro+
    multiLayer:  true,   // Premium+
  },
})

Node.js SDK — @orvex/sdk

The official @orvex/sdk package provides a fully-typed TypeScript/JavaScript client. Supports Node.js 18+ and any environment with native fetch.

bash
npm install @orvex/sdk
typescript
import { OrvexClient, OrvexQuotaError, OrvexParseError } from "@orvex/sdk"

const client = new OrvexClient({
  apiKey:  process.env.ORVEX_API_KEY!,
  timeout: 30_000,
})

try {
  // Single file
  const { output } = await client.obfuscate({
    code:       luaSource,
    luaVersion: "fivem",
    options: { vmInjection: true },
  })
  await fs.writeFile("dist/main.lua", output)

  // Batch (Pro+)
  const { results } = await client.obfuscateBatch({
    files: [
      { path: "server/main.lua",   code: await fs.readFile("server/main.lua",   "utf8") },
      { path: "server/config.lua", code: await fs.readFile("server/config.lua", "utf8") },
    ],
    luaVersion: "fivem",
  })
  for (const r of results) {
    if (r.ok) await fs.writeFile(`dist/${r.path}`, r.output!)
    else console.error(r.path, r.error)
  }
} catch (err) {
  if (err instanceof OrvexQuotaError)  console.error("Quota exceeded")
  else if (err instanceof OrvexParseError) console.error("Syntax error at", err.location)
  else throw err
}

CI/CD Integration

Protect scripts automatically as part of your build pipeline. Store your API key as a repository secret — never hard-code it.

yaml
# .github/workflows/protect.yml
name: Protect Lua scripts

on:
  push:
    branches: [main]

jobs:
  protect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - run: npm install @orvex/sdk

      - run: node scripts/protect.mjs
        env:
          ORVEX_API_KEY: ${{ secrets.ORVEX_API_KEY }}
javascript
// scripts/protect.mjs
import { OrvexClient } from "@orvex/sdk"
import { readFile, writeFile, mkdir } from "fs/promises"
import { glob } from "glob"

const client = new OrvexClient({ apiKey: process.env.ORVEX_API_KEY })

const files = await glob("server/**/*.lua")
await mkdir("dist/server", { recursive: true })

const { results } = await client.obfuscateBatch({
  files: await Promise.all(
    files.map(async path => ({ path, code: await readFile(path, "utf8") }))
  ),
  luaVersion: "fivem",
})

let failed = 0
for (const r of results) {
  if (r.ok) {
    await writeFile(`dist/${r.path}`, r.output)
    console.log("✓", r.path)
  } else {
    console.error("✗", r.path, r.error)
    failed++
  }
}

if (failed > 0) process.exit(1)

Ready to protect your scripts?

Start for free — no credit card required. Upgrade when you need API access or more obfuscations.