This page documents the JSO HTTP API at the protocol level. If we ship a language client for your runtime, use that; everything below is what the client does under the hood. If we don't ship a client for your runtime, this page contains everything you need to write one — the seven existing clients are 200–400 lines each and use exactly this shape.
Request shape
POST a single JSON object to HttpApi.ashx. The object carries credentials, the file list, the project name, an optional release label, and any number of protection options. Options are documented individually in the rest of the Docs catalog; the option keys are Pascal-case strings whose values are usually booleans.
{
"APIKey": "<base64-api-key-from-dashboard>",
"APIPwd": "<base64-api-password-from-dashboard>",
"Name": "release-tag-or-project-name",
"ReleaseLabel": "ci-build-7f3a", // optional, surfaces in the audit log
"Items": [
{ "FileName": "app.js", "FileCode": "let x = 1;" },
{ "FileName": "vendor.js", "FileCode": "..." }
],
// Preset options, then any explicit overrides.
"Compress": true,
"EncodeStrings": true,
"EncryptStrings": true,
"MoveStringsIntoArray": true,
"NameMangling": true,
"DeepObfuscate": true,
"FlatTransform": true,
"CodeTransposition": true,
// Optional locks (see the per-option docs).
"LockDate": true,
"LockDateValue": "20271231",
"LockDomain": true,
"LockDomainList": "example.com\nstaging.example.com"
}
The credential fields (APIKey, APIPwd) carry the base-64 values shown in the JSO dashboard under Account → API. They are NOT separate plaintext key/secret pairs — the dashboard hands you two opaque base-64 strings; pass them through verbatim.
Preset constants
Every language client ships the same three preset tables. If you write a client from scratch, embed these literals:
standard = {
Compress, EncodeStrings, MoveStringsIntoArray, NameMangling
}
balanced = {
Compress, EncodeStrings, EncryptStrings, MoveStringsIntoArray, NameMangling,
DeepObfuscate, FlatTransform, CodeTransposition
}
maximum = {
Compress, EncodeStrings, EncryptStrings, MoveStringsIntoArray, NameMangling,
DeepObfuscate, FlatTransform, CodeTransposition,
ProtectMembers, RenameGlobals, MoveMembers, DeadCodeInsertion
}
Every key listed above maps to a boolean. The server applies the preset then any explicit overrides, so {"FlatTransform": false, ...balanced} would disable that single transform without touching the rest of the preset.
Response shape on success
HTTP 200 with a body like:
{
"Type": "Succeed",
"Items": [
{ "FileName": "app.js", "FileCode": "<protected source>" },
{ "FileName": "vendor.js", "FileCode": "<protected source>" }
],
"Report": {
"BuildId": "rel-abcdef123",
"PolymorphismFingerprint": "1234567890abcdef",
"EnabledOptions": ["EncodeStrings", "NameMangling", "FlatTransform", ...],
"GlobalIdentifierMap": [
{ "Mangled": "_0x2a3b", "Original": "calculateLicenseHash" },
...
],
"MemberIdentifierMap": [
{ "Mangled": "_0xae", "Original": "productKey" },
...
],
"InputBytes": 12345,
"OutputBytes": 18432,
"GeneratedUtc": "2026-05-20T10:14:22Z"
// ... additional release-metadata fields documented in the per-option pages.
}
}
The Items array order is not guaranteed to match the request — match by FileName. Filenames are normalized to forward-slashes regardless of how they were sent.
Audit-friendly fields:
BuildId — stable identifier for this protection run. Inject as a global into your runtime so production crash reports carry the matching BuildId.
PolymorphismFingerprint — short SHA-256-derived token over the protected output. Two consecutive obfuscations of identical input MUST produce different fingerprints when polymorphism is engaged.
GlobalIdentifierMap + MemberIdentifierMap — demangling tables for stack-trace symbolication. Persist alongside the protected dist; feed to jso-symbolicate when a production crash arrives.
Response shape on failure
HTTP 200 still — failures are signalled in the body via a non-Succeed Type. Treat any of these as a hard error:
{
"Type": "Error",
"Message": "Invalid API key",
"ErrorCode": "AUTH_FAIL"
}
| Type | Meaning | Suggested action |
Succeed | Protection completed. | Continue. |
Error | Authentication, quota, or input validation failure. | Read Message and ErrorCode; fix and retry. |
SourceError | JS parse error in one of the input files. | Read FileName + LineNumber; fix the source. |
Exception / ServerException | Unexpected server-side failure. | Retry; if it recurs, contact support with the ExceptionToString. |
HTTP 4xx and 5xx responses are also possible (rate limits, gateway errors, etc.). Treat any non-2xx status as a transport-level failure.
Headers
The server is forgiving about request headers, but the recommended set is:
POST /HttpApi.ashx HTTP/1.1
Host: www.javascriptobfuscator.com
Content-Type: text/json
Content-Length: <byte length of the JSON body>
User-Agent: <your-client-name>/<version>
Use a unique User-Agent for each language client so support can correlate dashboard audit logs with client versions. Every shipped JSO client follows the jso-protector-<lang>/<semver> convention.
Reference implementation in shell
The smallest possible compliant client — useful when the language you need isn't covered above:
#!/usr/bin/env bash
set -euo pipefail
cat > payload.json <<EOF
{
"APIKey": "$JSO_API_KEY",
"APIPwd": "$JSO_API_PASSWORD",
"Name": "bash-session",
"ReleaseLabel": "$(git rev-parse HEAD)",
"Items": [ { "FileName": "app.js", "FileCode": $(jq -Rs . < dist/app.js) } ],
"Compress": true, "EncodeStrings": true, "EncryptStrings": true,
"MoveStringsIntoArray": true, "NameMangling": true,
"DeepObfuscate": true, "FlatTransform": true, "CodeTransposition": true
}
EOF
curl -fsS -X POST \
-H "Content-Type: text/json" \
-H "User-Agent: jso-curl/0.1" \
--data @payload.json \
https://www.javascriptobfuscator.com/HttpApi.ashx \
| jq '.Items[0].FileCode' -r > dist-protected/app.js
That covers the minimum surface. Anything more sophisticated — preset switching, structured error handling, identifier-map persistence — should crib from the existing language clients linked from the clients matrix.
JSON Schema
A machine-readable Draft 2020-12 JSON Schema for the request and response shapes lives at /Docs/wire-format.schema.json. Feed it into openapi-generator, quicktype, datamodel-code-generator, or any other JSON-Schema-to-types tool to generate a typed client in any language we don't already ship.
npx quicktype --src https://www.javascriptobfuscator.com/Docs/wire-format.schema.json \
--src-lang schema --lang kotlin -o JsoWireFormat.kt
The schema documents every preset key plus the audit-friendly Report fields. Additive-only versioning is in scope — new optional fields appear over time; existing fields are never removed or renamed.
Stability and versioning
The API is additive-only. Fields documented on this page have been stable since 2026-Q1; new fields appear from time to time but existing fields are never removed or renamed. Your client should ignore unknown fields in the response (every shipped JSO client does).
If we ever need to make a breaking change, it will live at a versioned endpoint (/v2/HttpApi.ashx) and the current endpoint will continue to work for at least 12 months after announcement on the roadmap.
Authentication: the API is for paid accounts. Free-tier users can use the
online obfuscator for evaluation; the HTTP API is gated by the same Basic+ tier required for the npm CLI.