{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://javascriptobfuscator.com/docs/wire-format.schema.json", "title": "JSO HTTP API wire format", "description": "Request and response shape for the JavaScript Obfuscator HTTP API (HttpApi.ashx). Use this schema with openapi-generator, quicktype, datamodel-code-generator, or any other JSON-Schema-to-types tool to generate a typed client in a language we don't already ship.", "$defs": { "ProtectRequest": { "type": "object", "description": "POST body for HttpApi.ashx. Combines credentials, the file list, and any number of protection options.", "required": ["APIKey", "APIPwd", "Items"], "additionalProperties": true, "properties": { "APIKey": { "type": "string", "minLength": 1, "description": "Base64-encoded API key from the JSO dashboard. NOT a separate plaintext key â pass the opaque base-64 string through verbatim." }, "APIPwd": { "type": "string", "minLength": 1, "description": "Base64-encoded API password from the JSO dashboard." }, "Name": { "type": "string", "description": "Project name surfaced in the dashboard audit log. Default per language client: 'python-session', 'dotnet-session', etc.", "default": "default" }, "ReleaseLabel": { "type": "string", "description": "Optional release tag forwarded with the request. Use the commit SHA for CI runs to group audit entries by commit." }, "Items": { "type": "array", "minItems": 1, "description": "Files to protect. The response Items array is keyed by FileName so order does not matter; filenames are normalized to forward-slashes regardless of how they are sent.", "items": { "$ref": "#/$defs/ProtectItem" } }, "Compress": { "type": "boolean", "description": "Standard/balanced/maximum: compact whitespace and structural redundancy in the output." }, "EncodeStrings": { "type": "boolean", "description": "Standard/balanced/maximum: encode string literals using a per-build encoding." }, "EncryptStrings": { "type": "boolean", "description": "Balanced/maximum: cryptographically encrypt the hoisted string pool." }, "MoveStringsIntoArray": { "type": "boolean", "description": "Standard/balanced/maximum: hoist all string literals into a single indexed array." }, "NameMangling": { "type": "boolean", "description": "Standard/balanced/maximum: rename local identifiers to short opaque tokens." }, "DeepObfuscate": { "type": "boolean", "description": "Balanced/maximum: deeper transforms on nested scope and identifier shadowing." }, "FlatTransform": { "type": "boolean", "description": "Balanced/maximum: control-flow flattening â linear code becomes a state-machine loop." }, "CodeTransposition": { "type": "boolean", "description": "Balanced/maximum: reorder statements while preserving semantics." }, "ProtectMembers": { "type": "boolean", "description": "Maximum: rename non-public object property names." }, "RenameGlobals": { "type": "boolean", "description": "Maximum: rename globals (be careful â escapes the bundle by definition)." }, "MoveMembers": { "type": "boolean", "description": "Maximum: relocate member declarations across scope boundaries." }, "DeadCodeInsertion": { "type": "boolean", "description": "Maximum: splice in provably-unreachable branches to grow the decompiler's search space." }, "LockDate": { "type": "boolean", "description": "Lock the protected build to expire after LockDateValue." }, "LockDateValue": { "type": "string", "pattern": "^[0-9]{8}$", "description": "Expiration date in YYYYMMDD format. Use with LockDate=true." }, "LockDateMsg": { "type": "string", "description": "Optional message displayed when the runtime detects expiry." }, "LockStartDate": { "type": "boolean", "description": "Prevent the protected build from running before LockStartDateValue." }, "LockStartDateValue": { "type": "string", "pattern": "^[0-9]{8}$", "description": "Activation date in YYYYMMDD format. Use with LockStartDate=true." }, "LockStartDateMsg": { "type": "string", "description": "Optional message used when the runtime detects an early launch." }, "LockBrowser": { "type": "boolean", "description": "Restrict execution to the canonical names in LockBrowserList using browser runtime signals." }, "LockBrowserList": { "type": "string", "description": "Comma or newline-separated allowlist: chrome, edge, firefox, safari, opera, ie." }, "LockBrowserMsg": { "type": "string", "description": "Optional message used when the browser allowlist fails." }, "LockOS": { "type": "boolean", "description": "Restrict execution to the canonical names in LockOSList using browser runtime signals." }, "LockOSList": { "type": "string", "description": "Comma or newline-separated allowlist: windows, macos, linux, android, ios." }, "LockOSMsg": { "type": "string", "description": "Optional message used when the operating-system allowlist fails." }, "LockDomain": { "type": "boolean", "description": "Lock the protected build to one of LockDomainList." }, "LockDomainList": { "type": "string", "description": "Newline-separated list of domains the protected output is allowed to run on." }, "LockDomainRedirectUrl": { "type": "string", "description": "Domain-lock-specific HTTP(S) or same-origin root-relative redirect target." }, "ReservedStrings": { "type": "string", "maxLength": 51300, "description": "Up to 100 newline-delimited regular expressions for literals that must remain verbatim and outside string move/encode transforms." }, "ForceTransformStrings": { "type": "string", "maxLength": 51300, "description": "Up to 100 newline-delimited regular expressions that override ReservedStrings for matching literals." }, "SplitStrings": { "type": "boolean", "description": "Split eligible string literals into fixed-length concatenated chunks." }, "SplitStringsChunkLength": { "type": "integer", "minimum": 1, "maximum": 1024, "default": 10 }, "StringArrayIndexShift": { "type": "boolean", "description": "Offset moved-string table references by one nonzero slot." }, "StringArrayShuffle": { "type": "boolean", "description": "Randomize moved-string table order while preserving generated lookups." }, "StringArrayRotate": { "type": "boolean", "description": "Cyclically rotate moved-string table order by a per-build offset." }, "StringArrayIndexesType": { "type": "string", "pattern": "^(hexadecimal-number|hexadecimal-numeric-string)(\\n(hexadecimal-number|hexadecimal-numeric-string))*$", "description": "Newline-delimited hexadecimal lookup representations." }, "StringArrayThreshold": { "type": "number", "minimum": 0, "maximum": 1, "description": "Probability that each unique eligible literal enters the moved-string table." }, "StringArrayCallsTransform": { "type": "boolean", "description": "Route selected moved-string lookups through a secondary index table." }, "StringArrayCallsTransformThreshold": { "type": "number", "minimum": 0, "maximum": 1, "description": "Probability that each moved-string lookup receives secondary indirection." }, "StringArrayWrappersCount": { "type": "integer", "minimum": 0, "maximum": 10, "description": "Root-level string-table wrapper count." }, "StringArrayWrappersChainedCalls": { "type": "boolean", "description": "Delegate generated wrappers through predecessors." }, "StringArrayWrappersParametersMaxCount": { "type": "integer", "minimum": 2, "maximum": 5, "description": "Function-wrapper parameter ceiling." }, "StringArrayWrappersType": { "type": "string", "enum": ["variable", "function"], "description": "Wrapper implementation style." }, "TransformObjectKeys": { "type": "boolean", "description": "Move safe object-literal data keys into computed string-table lookups." }, "DebugProtection": { "type": "boolean", "description": "Runtime Defense: throw on detectable debugger attach." }, "DebugProtectionIntervalMilliseconds": { "type": "integer", "minimum": 0, "maximum": 60000, "description": "Periodic debug timing probe interval. Use 0 or 100-60000 milliseconds." }, "DisableConsoleOutput": { "type": "boolean", "description": "Runtime Defense: blackhole console.log / warn / error in the protected scope." }, "SelfDefending": { "type": "boolean", "description": "Runtime Defense: integrity-heartbeat guard. Trips when the protected source is edited." }, "AntiMonkeyPatching": { "type": "boolean", "description": "Runtime Defense: snapshots selected browser APIs and trips if they are replaced after startup. Browser-only; default false." }, "AntiMonkeyPatchingMsg": { "type": "string", "description": "Optional message used when AntiMonkeyPatching detects a replaced API." }, "SelfDefendingIntervalSeconds": { "type": "integer", "minimum": 1, "maximum": 86400, "description": "Heartbeat interval. Lower = more frequent checks = higher detection rate, slightly higher overhead." }, "BlockDevToolsKeys": { "type": "boolean", "description": "Block F12, Ctrl+Shift+I, and similar devtools-trigger keystrokes in the protected scope." }, "DetectHeadlessBrowser": { "type": "boolean", "description": "Trip the Runtime Defense beacon when running under Puppeteer/Playwright/Selenium." } } }, "ProtectItem": { "type": "object", "required": ["FileName", "FileCode"], "additionalProperties": false, "properties": { "FileName": { "type": "string", "minLength": 1, "description": "Logical filename. Forward-slash separators; the server normalizes backslashes." }, "FileCode": { "type": "string", "description": "Source code as a UTF-8 string. Pass the file contents verbatim â no encoding, no escaping." } } }, "ProtectResponse": { "type": "object", "description": "Body shape returned by HttpApi.ashx. HTTP 2xx; failure modes are signalled in the body via a non-Succeed Type.", "required": ["Type"], "additionalProperties": true, "properties": { "Type": { "type": "string", "enum": ["Succeed", "Error", "SourceError", "Exception", "ServerException", "LoginFailed"], "description": "Outcome tag. Only 'Succeed' is success; everything else is a hard error." }, "Items": { "type": "array", "description": "Protected source per input file. Present iff Type=Succeed.", "items": { "$ref": "#/$defs/ProtectItem" } }, "Report": { "$ref": "#/$defs/ProtectReport", "description": "Audit metadata. Present iff Type=Succeed." }, "Message": { "type": "string", "description": "Human-readable failure message. Present when Type != Succeed." }, "ErrorCode": { "type": "string", "description": "Stable failure code for programmatic routing. Present when Type != Succeed." }, "FileName": { "type": "string", "description": "Offending filename when Type=SourceError." }, "LineNumber": { "type": ["string", "integer"], "description": "Offending line when Type=SourceError." }, "ExceptionToString": { "type": "string", "deprecated": true, "description": "Local-development diagnostic only. Remote production failures omit this field and provide an opaque support reference in Message." } } }, "ProtectReport": { "type": "object", "description": "Audit-friendly metadata for a successful protection run.", "additionalProperties": true, "properties": { "BuildId": { "type": "string", "description": "Stable identifier for this protection run. Inject as a global into your runtime so production crash reports carry the matching BuildId." }, "PolymorphismFingerprint": { "type": "string", "description": "Short SHA-256-derived fingerprint over the protected output. Two consecutive obfuscations of identical input MUST produce different fingerprints when polymorphism is engaged." }, "EnabledOptions": { "type": "array", "items": { "type": "string" }, "description": "List of API option names that the server actually applied." }, "GlobalIdentifierMap": { "type": "array", "description": "Mangled-to-original mapping for renamed global identifiers. Persist alongside the protected dist; feed to jso-symbolicate when a production crash arrives.", "items": { "$ref": "#/$defs/IdentifierMapEntry" } }, "MemberIdentifierMap": { "type": "array", "description": "Mangled-to-original mapping for renamed object members.", "items": { "$ref": "#/$defs/IdentifierMapEntry" } }, "InputBytes": { "type": "integer", "minimum": 0 }, "OutputBytes": { "type": "integer", "minimum": 0 }, "InputFiles": { "type": "integer", "minimum": 0 }, "OutputFiles": { "type": "integer", "minimum": 0 }, "InputLines": { "type": "integer", "minimum": 0 }, "OutputLines": { "type": "integer", "minimum": 0 }, "GeneratedUtc": { "type": "string", "format": "date-time" } } }, "IdentifierMapEntry": { "type": "object", "required": ["Mangled", "Original"], "additionalProperties": false, "properties": { "Mangled": { "type": "string", "description": "Mangled identifier as it appears in the protected source." }, "Original": { "type": "string", "description": "Original identifier name from the input source." } } } }, "oneOf": [ { "$ref": "#/$defs/ProtectRequest" }, { "$ref": "#/$defs/ProtectResponse" } ] }