Vanta Obfuscator
Protection API

API Documentation

Protect Luau source from your own code: one endpoint, one key, no tiers. Free like everything else on Vanta.

Quickstart

curl -X POST https://vantaobf.pages.dev/api/obfuscate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"source":"local msg = \"hello from vanta\"\nprint(msg)","preset":"balanced"}'

Your API key is on your dashboard, under API or Settings. Every account gets one on signup.

Authentication

Send your key as a Bearer token, or in an X-API-Key header:

Authorization: Bearer vk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X-API-Key: vk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys look like vk_ followed by 40 hex characters. Regenerate yours any time from the dashboard (Settings or API view). Treat it like a password: it protects builds under your account.

POST /api/obfuscate

Protects Luau/Lua source with the same engine the web app and CLI use, saves the build to your dashboard, and returns the protected output.

FieldTypeDefaultNotes
sourcestring—Required. Luau source. Up to 200,000 characters.
presetstringengine defaultsbasic | balanced | strong | maximum | vm (aliases: lightweight, paranoid)
junk0–43Control-flow variation. 3/4 grow output a lot (4 can reach ~2 MB).
flatten0–20Control-flow flattening: off | loop-free | + loop bodies.
mba0–20Mixed Boolean-arithmetic on integer constants.
seedstringrandomDeterministic builds: same source + same seed = byte-identical output.
namestring"API build"Label shown in your dashboard build list.
renamebooltrueSymbol-aware local identifier renaming.
watermarkbooltrueLeading protection notice.
minifybooltrueOne-line output.
anti_tamper0–22Decoder integrity checks. Also accepts antiTamper.
vm_modestringbalancedfast | balanced | secure. Also accepts vmMode.
vm_layers1–101Stacked VM layers. Keep 1 for executors like Delta. Also accepts vmLayers.
guard0–22VM-prerequisite validation level.
compressionboolfalseRLE payload size pass.
exec_budgetint0Refuse to run past N VM instructions (0 = off). Also accepts execBudget.
lock_place / lock_universestring—Bind the build to a Roblox place / universe id. Also accepts lockPlace / lockUniverse.

Response, 200 OK:

{ "ok": true, "build_id": "b7f2c3a1-...", "seed": "cyr-normal-1", "output": "-- Protected by Vanta Obfuscator\n...", "output_size": 247165, "stats": { "seed": "cyr-normal-1", "...": "engine timings and counts" } }

Limits

PriceFree. No tiers, no keys to buy, no daily cap on accounts.
Builds per key30 per hour (rolling window). Over the limit returns 429.
Source size200,000 characters per request (413 above).
BytecodeNot available through the API: bytecode builds need the local Luau compiler. Use the CLI: vanta --bytecode.

Errors

StatusWhen
400Malformed JSON, missing source, unknown preset, or the engine rejected your source (parse/validate error — the message tells you why).
401Missing or invalid API key.
405Wrong method; the endpoint is POST-only.
413Source over 200,000 characters.
429Over 30 builds this hour on your key.
500Engine error. Retrying with the same input gives the same result; check the message and your source.

Examples

Python

import requests r = requests.post( "https://vantaobf.pages.dev/api/obfuscate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={"source": open("script.luau").read(), "preset": "maximum", "seed": "my-seed-1"}, ) r.raise_for_status() open("script.protected.luau", "w").write(r.json()["output"])

Node.js

const res = await fetch("https://vantaobf.pages.dev/api/obfuscate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ source: myLuauSource, preset: "strong" }), }); const { output } = await res.json();

Luau (from Roblox)

local HttpService = game:GetService("HttpService") local res = request({ Url = "https://vantaobf.pages.dev/api/obfuscate", Method = "POST", Headers = { ["Authorization"] = "Bearer YOUR_API_KEY", ["Content-Type"] = "application/json", }, Body = HttpService:JSONEncode({ source = scriptSource, preset = "balanced", }), }) local out = HttpService:JSONDecode(res.Body).output
Builds made through the API are saved to your dashboard like manual ones, so you can always re-download a protected output later.

Determinism

Pass a seed and the same source with the same options always produces byte-identical output. Leave it off and every build gets a fresh random seed. This matters if you verify builds in CI or diff protected files between versions.