API

Deniable encryption as a service. Register for a key, encrypt in one call.


Authentication

All endpoints (except registration and health) require a Bearer token:

Authorization: Bearer dk_your_api_key_here

Get an API key

POST /api/register

{
  "email": "you@example.com",
  "name": "My App"          // optional
}

→ 201
{
  "key": "dk_abc123...",
  "tier": "free",
  "monthly_limit": 100,
  "message": "Store your API key securely."
}

One key per email. If you've already registered, you'll get a 409 response. Store your key when you first receive it.


Encrypt

POST /api/encrypt

{
  "message": "launch codes: 38.8977° N, 77.0365° W",
  "password1": "correct-horse",
  "password2": "battery-staple"
}

→ 200
{
  "ciphertext": "a3f2...hex",
  "controlData": "b7c1...hex"
}

Store both the ciphertext and control data. You need the control data to decrypt or create decoys.


Decrypt

POST /api/decrypt

{
  "ciphertextHex": "a3f2...hex",
  "controlDataHex": "b7c1...hex",
  "password1": "correct-horse",
  "password2": "battery-staple"
}

→ 200
{
  "message": "launch codes: 38.8977° N, 77.0365° W"
}

Create decoy

This is the core feature. Generate new control data that makes the same ciphertext decrypt to a completely different message.

POST /api/deny

{
  "ciphertextHex": "a3f2...hex",
  "password1": "correct-horse",
  "password2": "battery-staple",
  "fakeMessage": "grocery list: milk, eggs, bread"
}

→ 200
{
  "controlData": "d4e5...hex"
}

// Now decrypt the SAME ciphertext with the new control data:
POST /api/decrypt
{
  "ciphertextHex": "a3f2...hex",          // same ciphertext
  "controlDataHex": "d4e5...hex",          // new control data
  "password1": "correct-horse",
  "password2": "battery-staple"
}

→ 200
{
  "message": "grocery list: milk, eggs, bread"  // different truth
}

Check usage

GET /api/usage

→ 200
{
  "tier": "free",
  "calls_this_month": 42,
  "limit": 100,
  "remaining": 58,
  "resets_at": "2026-05-01T00:00:00.000Z"
}

Pricing

Free Dev - $19/mo Pro - $49/mo
Monthly calls 100 10,000 100,000
Endpoints All All All
Support GitHub Email Priority

To upgrade, email hello@deny.sh


Errors

All errors return JSON with an error field:

{ "error": "Missing or invalid API key" }    // 401
{ "error": "Monthly limit reached" }          // 429
{ "error": "Required: message, password1..." } // 400
{ "error": "Decryption failed: ..." }         // 400