← All docs

API documentation

One endpoint, one key. POST your Luau source — get back a protected build.

Overview

The API lives at https://limeobf.com/api/. Requests are POST with a JSON body; responses are JSON. It's stateless from your side — no jobs, no polling, no webhooks. Send source, get the protected build back.

Your source is compiled in-request and never stored. The full protection engine is applied automatically — there's nothing to configure.

Authentication

Every request needs an X-API-Key header. Keys look like lobf_ followed by 28 hex characters. Get one from the LimeHub shop — it's emailed to you instantly. Note: API access is on the Pro plan and up.

curl -X POST https://limeobf.com/api/vm-compile \
  -H "X-API-Key: lobf_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"source":"print(\"hello\")"}'

Errors

StatusMeaning
200Success — ok: true in the body.
400Missing source or malformed JSON.
401Missing, invalid, or revoked X-API-Key.
422Source failed to parse or compile — detail has the message.
429Monthly compile limit reached for this key. Resets at the start of each month.
500Internal error. Retry once; report if it persists.

Errors return {"error":"...","detail":"..."}.

Monthly limits

Each key has a monthly compile limit set by your plan. Once you hit it, further compiles return 429 until the counter resets at the start of the next month. You can watch your usage live in the dashboard.

PlanCompiles / month
Basic500
Premium2,000
Pro6,000
EnterpriseUnlimited

POST /api/vm-compile

The one endpoint you need. Your source is compiled into a unique, protected build. Pick the engine with mode: block (default) — a fast register-VM, smallest on short scripts; or interp — the maximum-protection opcode-VM (anti-dump / anti-devirtualization / anti-tamper). interp has a fixed-size engine, so it's larger on tiny scripts but more compact than block on real/large scripts.

Request

FieldTypeDescription
sourcestringYour Luau / Lua source. Required.
modestring"block" (default) — per-block register-VM; fastest runtime; smallest on short scripts, but output grows steeply with source size. "interp" — opcode-VM with the full anti-dump / anti-devirtualization / anti-tamper stack; fixed-size engine + compact bytecode, so on real/large scripts it ends up smaller than block; slower runtime. Optional.
obfuscateboolLayer extra source-level obfuscation on top. Optional, default true.
headerboolPrepend a brand comment line. Optional, default false.

Response

outputstringThe protected Luau source — drop it in and run.
okboolAlways true on success.
bytes_inintInput length.
bytes_outintOutput length.
Tip: the macro system lets you control protection per-function right in your source — mark a hot loop native with LMO_NO_VIRTUALIZE, force full encryption with LMO_ENCFUNC, and more.

GET /health

Liveness probe. No auth. Returns {"ok":true,"service":"limeobf"}.

Example — curl

curl -X POST https://limeobf.com/api/vm-compile \
  -H "X-API-Key: $LIMEOBF_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<'EOF'
{ "source": "local function fact(n) if n <= 1 then return 1 end return n * fact(n - 1) end print(fact(8))" }
EOF

Add "mode":"interp" for the maximum-protection engine:

  -d '{ "source": "print(\"hello\")", "mode": "interp" }'

Example — Python

import os, json, urllib.request

req = urllib.request.Request(
    "https://limeobf.com/api/vm-compile",
    data=json.dumps({"source": open("script.lua").read()}).encode(),
    headers={"Content-Type": "application/json",
             "X-API-Key": os.environ["LIMEOBF_KEY"]})
with urllib.request.urlopen(req) as r:
    print(json.load(r)["output"])

Example — JavaScript (Node)

const res = await fetch("https://limeobf.com/api/vm-compile", {
  method: "POST",
  headers: { "Content-Type": "application/json",
             "X-API-Key": process.env.LIMEOBF_KEY },
  body: JSON.stringify({ source: await fs.promises.readFile("script.lua","utf8") }),
});
console.log((await res.json()).output);

Example — Roblox HttpService

For runtime use from inside an executor. For production, compile offline and ship the output.

local Http = game:GetService("HttpService")
local req = (syn and syn.request) or (http and http.request)
        or (fluxus and fluxus.request) or request

local res = req({
    Url = "https://limeobf.com/api/vm-compile",
    Method = "POST",
    Headers = { ["Content-Type"]="application/json",
                ["X-API-Key"]="lobf_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
    Body = Http:JSONEncode({ source = [[print("hello")]] }),
})
local out = Http:JSONDecode(res.Body).output
(loadstring or load)(out)()