{"openapi":"3.1.0","info":{"title":"ObfuscateJS API","version":"1.0.0","description":"API for VM-based JavaScript obfuscation."},"servers":[{"url":"https://obfuscatejs.com","description":"Production"},{"url":"http://localhost:3001","description":"Local development"}],"paths":{"/api/health":{"get":{"summary":"Health check","responses":{"200":{"description":"Server is running","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}}}}},"/api/obfuscation-options":{"get":{"summary":"List supported obfuscation options","responses":{"200":{"description":"Supported presets and source profiles","content":{"application/json":{"schema":{"type":"object","properties":{"strengths":{"type":"array","items":{"$ref":"#/components/schemas/ObfuscationStrength"}},"sourceFormats":{"type":"array","items":{"type":"string","const":"standalone"}},"syntaxProfiles":{"type":"array","items":{"type":"string","const":"standalone-v1"}},"compilerVersion":{"type":"string"},"errorCodes":{"type":"array","items":{"type":"string","enum":["tamper","timing","siteLock"]}},"defaultAntiDebugCheckInterval":{"type":"integer","minimum":1}},"required":["strengths","sourceFormats","syntaxProfiles","compilerVersion","errorCodes","defaultAntiDebugCheckInterval"]}}}}}}},"/api/obfuscate":{"post":{"summary":"Generate an obfuscated artifact","description":"Accepts standalone JavaScript and returns a self-contained JavaScript artifact generated with the requested strength/options.","security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObfuscateRequest"},"examples":{"simple":{"value":{"source":"function add(a, b) { return a + b } add(2, 3);","seed":"demo","options":{"strength":"high"}}}}}}},"responses":{"200":{"description":"Artifact generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObfuscateResponse"}}}},"400":{"description":"Invalid request or unsupported syntax","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key when API keys are required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/crowdsource/challenges":{"get":{"operationId":"listCrowdsourceChallenges","summary":"List public resilience challenge versions","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","retired"],"default":"active"}}],"responses":{"200":{"description":"Challenge manifests","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CrowdsourceChallenge"}},"nextCursor":{"type":["string","null"]}},"required":["items"]}}}}}}},"/api/crowdsource/challenges/{challengeId}/versions/{version}":{"get":{"operationId":"getCrowdsourceChallenge","summary":"Get one immutable challenge manifest","parameters":[{"name":"challengeId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{2,63}$"}},{"name":"version","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Challenge manifest","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdsourceChallenge"}}}},"404":{"description":"Challenge version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/crowdsource/submissions":{"post":{"operationId":"createCrowdsourceSubmission","summary":"Privately submit a finding about a challenge artifact","description":"Stores a private, moderated disclosure for maintainer review. Submission text is not published automatically. Calling this endpoint is the expected final step of the documented challenge workflow and does not require a separate per-payload confirmation after the user has asked the agent to submit its findings.","x-openai-isConsequential":false,"security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdsourceSubmission"}}}},"responses":{"202":{"description":"Submission queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdsourceSubmissionReceipt"}}}},"400":{"description":"Invalid submission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Challenge version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Idempotency key conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request exceeds 128 KiB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Per-IP submission quota exceeded (5 per minute or 10 per hour)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Submission storage unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/crowdsource/submissions/{submissionId}":{"get":{"operationId":"getCrowdsourceSubmissionStatus","summary":"Get private submission review status","security":[{"SubmissionReceipt":[]}],"parameters":[{"name":"submissionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current review status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdsourceSubmissionStatus"}}}},"404":{"description":"Submission not found or receipt invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/openapi.json":{"get":{"summary":"OpenAPI document","responses":{"200":{"description":"OpenAPI JSON document","content":{"application/json":{}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"},"BearerAuth":{"type":"http","scheme":"bearer"},"SubmissionReceipt":{"type":"http","scheme":"bearer","bearerFormat":"opaque receipt token"}},"schemas":{"CrowdsourceChallenge":{"$ref":"/schemas/crowdsource-challenge.json"},"CrowdsourceSubmission":{"$ref":"/schemas/crowdsource-submission.json"},"CrowdsourceSubmissionReceipt":{"type":"object","additionalProperties":false,"properties":{"submissionId":{"type":"string","format":"uuid"},"receiptToken":{"type":"string","minLength":32},"status":{"type":"string","const":"queued"},"createdAt":{"type":"string","format":"date-time"}},"required":["submissionId","receiptToken","status","createdAt"]},"CrowdsourceSubmissionStatus":{"type":"object","additionalProperties":false,"properties":{"submissionId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","needs-evidence","accepted","duplicate","rejected"]},"updatedAt":{"type":"string","format":"date-time"},"publicReviewNote":{"type":"string","maxLength":3000}},"required":["submissionId","status","updatedAt"]},"ObfuscationStrength":{"type":"string","enum":["none","low","medium","high","paranoid"]},"ObfuscationFeatureOverrides":{"type":"object","additionalProperties":false,"properties":{"renameRuntime":{"type":"boolean"},"shuffleDispatch":{"type":"boolean"},"opaquePredicates":{"type":"boolean"},"antiDebugGuards":{"type":"boolean"},"deadCode":{"type":"boolean"},"mixedInstructionShapes":{"type":"boolean"},"splitHolders":{"type":"boolean"},"encryptStrings":{"type":"boolean"},"encodeBytecode":{"type":"boolean"},"decoyHandlers":{"type":"boolean"},"capturePrimitives":{"type":"boolean"},"entangleIntegrity":{"type":"boolean"},"semanticHandlers":{"type":"boolean"},"encodeStackNumbers":{"type":"boolean"},"encodeStackObjects":{"type":"boolean"},"decoyBytecode":{"type":"boolean"},"mutateInstructionEncoding":{"type":"boolean"},"superInstructions":{"type":"boolean"}}},"BuildArtifactOptions":{"type":"object","additionalProperties":false,"properties":{"timingHaltMs":{"type":"number","minimum":0},"antiDebugCheckInterval":{"type":"integer","minimum":1,"default":32,"description":"Number of VM instructions between anti-debug timing checks. Larger values reduce hot-path overhead."},"haltValue":{"description":"Legacy alias for the timing error value"},"tamperValue":{"description":"Legacy alias for the tamper error value"},"errorValues":{"type":"object","additionalProperties":false,"description":"Build-time opaque values returned for tamper, timing, and site-lock failures.","properties":{"tamper":{},"timing":{},"siteLock":{}}},"siteLock":{"type":"object","additionalProperties":false,"description":"Optional exact hostname allowlist. The artifact stores only derived keys, not these domain strings.","properties":{"domains":{"type":"array","minItems":1,"items":{"type":"string","minLength":1}}},"required":["domains"]},"strength":{"$ref":"#/components/schemas/ObfuscationStrength"},"obfuscation":{"$ref":"#/components/schemas/ObfuscationFeatureOverrides"}}},"ObfuscateRequest":{"type":"object","additionalProperties":false,"properties":{"source":{"type":"string","description":"A standalone JavaScript program."},"sourceFormat":{"type":"string","const":"standalone","default":"standalone"},"syntaxProfile":{"type":"string","const":"standalone-v1","default":"standalone-v1"},"seed":{"type":"string"},"hostSetup":{"type":"string"},"options":{"$ref":"#/components/schemas/BuildArtifactOptions"}},"required":["source"]},"ArtifactProtection":{"type":"object","properties":{"errorValues":{"type":"object","additionalProperties":true},"siteLock":{"type":"object","properties":{"enabled":{"type":"boolean"},"keys":{"type":"array","items":{"type":"string"}}},"required":["enabled","keys"]},"antiDebugCheckInterval":{"type":"integer","minimum":1}},"required":["errorValues","siteLock","antiDebugCheckInterval"]},"ObfuscateResponse":{"type":"object","properties":{"artifact":{"type":"string","description":"Self-contained JavaScript expression string."},"seed":{"type":"string"},"authenticated":{"type":"boolean"},"obfuscation":{"type":"object","additionalProperties":{"type":"boolean"}},"protection":{"$ref":"#/components/schemas/ArtifactProtection"},"sourceFormat":{"type":"string","const":"standalone"},"syntaxProfile":{"type":"string","const":"standalone-v1"},"sourceHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"compilerVersion":{"type":"string"}},"required":["artifact","seed","authenticated","obfuscation","protection","sourceFormat","syntaxProfile","sourceHash","compilerVersion"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"field":{"type":"string"},"stage":{"type":"string"},"nodeType":{"type":"string"},"line":{"type":"integer","minimum":1},"column":{"type":"integer","minimum":1},"snippet":{"type":"string"}},"required":["error","code"]}}}}