POST Encrypt
Encrypt a message with two passwords. Returns ciphertext and control data (both hex-encoded).
POST /api/encrypt
{
"message": "launch codes: 38.8977 N, 77.0365 W",
"password1": "correct-horse",
"password2": "battery-staple",
"controlDataHex": "optional...hex" // optional: supply your own control data
}
200
{
"ciphertext": "a3f2...hex",
"controlData": "b7c1...hex"
}
| Parameter | Type | Description |
|---|---|---|
| message required | string | Plaintext to encrypt. Max 10MB. |
| password1 required | string | First password; both are required. Max 1024 chars. |
| password2 required | string | Second password; both are required. Max 1024 chars. |
| controlDataHex | string | Optional hex-encoded control data. Auto-generated if omitted. |
Store the ciphertext and real control data separately. Both passwords and the chosen control file are required to decrypt. Creating a decoy control file requires the ciphertext, both passwords and your chosen decoy message.
POST Decrypt
POST /api/decrypt
{
"ciphertext": "a3f2...hex",
"controlData": "b7c1...hex",
"password1": "correct-horse",
"password2": "battery-staple"
}
200
{
"message": "launch codes: 38.8977 N, 77.0365 W"
}
| Parameter | Type | Description |
|---|---|---|
| ciphertext required | string | Hex-encoded ciphertext. |
| controlData required | string | Hex-encoded control data. |
| password1 required | string | First password; both are required. |
| password2 required | string | Second password; both are required. |
POST Create decoy PAID
Create another control file that opens the same encrypted data to your chosen fake. Both passwords remain the same. This hosted endpoint requires paid API access and is separate from the decoy-suggestion service below.
POST /api/deny27 lines
POST /api/deny
{
"ciphertext": "a3f2...hex",
"password1": "correct-horse",
"password2": "battery-staple",
"fakeMessage": "grocery list: milk, eggs, bread"
}
200
{
"controlData": "d4e5...hex"
}
// Decrypt the SAME ciphertext with the new control data:
POST /api/decrypt
{
"ciphertext": "a3f2...hex", // same ciphertext
"controlData": "d4e5...hex", // new control data
"password1": "correct-horse",
"password2": "battery-staple"
}
200
{
"message": "grocery list: milk, eggs, bread" // different truth
}| Parameter | Type | Description |
|---|---|---|
| ciphertext required | string | Hex-encoded ciphertext from a previous encrypt call. |
| password1 required | string | Primary password (same as used for encryption). |
| password2 required | string | Secondary password (same as used for encryption). |
| fakeMessage required | string | The fake message, encoded as UTF-8. It must fit within the encrypted payload capacity, including its four-byte length prefix. Padded ciphertext may hold a fake longer than the original message. |
POST Suggest realistic decoys
The realism engine can suggest shape-correct decoy plaintexts before you create deniable control data. Authenticated calls use your API key's daily decoy allowance; unauthenticated calls from the public encrypt page use a small per-IP burst limit.
POST /v1/decoy/suggest
Authorization: Bearer dk_live_...
Content-Type: application/json
{ "explicit_type": "stripe-test-key", "n_decoys": 3 }
200
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1770019200
{
"type_detected": "stripe-test-key",
"decoys": [
{ "decoy_text": "sk_test_51Nz...", "plausibility_score": 0.94, "source": "llm" }
],
"cache_hit": false,
"generation_latency_ms": 842
}
Quota windows are sliding 24-hour windows. X-RateLimit-Reset is a Unix epoch second: for an allowed call it is roughly now plus 24 hours; after a 429 it is the time the oldest successful call leaves the window.
See current plans and allowances. Response headers report the allowance applied to your request.
POST /v1/decoy/suggest
429
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1770019200
Retry-After: 38142
{ "error": "tier_daily_limit", "limit": 10, "reset_at": 1770019200 }
The public no-auth path uses the same response headers, but the 429 body is { "error": "ip_burst_limit", "limit": 30, "reset_at": 1770019200 } and the window is 30 calls per IP per hour.
POST Text encrypt
Simplified text-only encryption. Returns hex strings directly (no binary). Control data is auto-generated.
POST /api/text/encrypt
{
"message": "my secret",
"password1": "demo-pass-one",
"password2": "demo-pass-two"
}
200
{
"ciphertextHex": "a3f2...hex",
"controlData": "b7c1...hex"
}
POST Text decrypt
Decrypt a text-encrypted message. Accepts both ciphertextHex and ciphertext field names.
POST /api/text/decrypt
{
"ciphertextHex": "a3f2...hex",
"controlData": "b7c1...hex",
"password1": "demo-pass-one",
"password2": "demo-pass-two"
}
200
{
"message": "my secret"
}
POST Generate control data
Generate random control data of a specific size. Useful when you want to manage control data separately from encryption.
POST /api/generate-control
{
"size": 1024
}
200
{
"controlData": "a1b2c3...hex"
}
| Parameter | Type | Description |
|---|---|---|
| size required | number | Byte length of control data. 1 to 10,485,760 (10MB). |