🔐 Cherami API

API Documentation

🚀 Getting Started

The Cherami API allows you to programmatically create and manage secure, self-destructing messages.

⚠️ Important: Client-Side Encryption Required

To maintain our zero-knowledge architecture, you MUST encrypt content on the client side before sending to our API. Decrypted content never touches our servers.

Base URL: https://cherami.link/api/v1

Authentication: All requests require a Bearer token in the Authorization header:

Authorization: Bearer ck_your_api_key_here

📝 Create Message

Create a new secure message that self-destructs after viewing or expiration.

Endpoint:

POST /api/v1/messages

Request Body:

{
  "encrypted_content": "base64_encrypted_content",
  "views_allowed": 1,
  "expires_in_minutes": 1440,
  "password_protected": false
}

Response:

{
  "id": "a7f3d8e9",
  "url": "https://cherami.link/view/a7f3d8e9",
  "expires_at": 1703721600,
  "views_remaining": 1
}

Example (JavaScript with Web Crypto API):

// 1. Generate encryption key
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"]
);

// 2. Encrypt message
const iv = crypto.getRandomValues(new Uint8Array(12));
const encoded = new TextEncoder().encode("Secret message");
const encrypted = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv },
  key,
  encoded
);

// 3. Prepare for API
const ivB64 = btoa(String.fromCharCode(...iv));
const encryptedB64 = btoa(String.fromCharCode(...new Uint8Array(encrypted)));
const keyB64 = btoa(String.fromCharCode(...new Uint8Array(
  await crypto.subtle.exportKey("raw", key)
)));

// 4. Send to API
const response = await fetch('https://cherami.link/api/v1/messages', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ck_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    encrypted_content: `${ivB64}.${encryptedB64}`,
    views_allowed: 1,
    expires_in_minutes: 60
  })
});

const result = await response.json();
// Append key to URL: result.url + '#' + encodeURIComponent(btoa(JSON.stringify({key: keyB64})))

📊 Check Message Status

Get the current status of a message you created.

Endpoint:

GET /api/v1/messages/{message_id}/status

Response:

{
  "id": "a7f3d8e9",
  "views_remaining": 0,
  "expires_at": 1703721600,
  "expired": false,
  "created_at": 1703635200
}

🗑️ Delete Message

Immediately delete a message you created.

Endpoint:

DELETE /api/v1/messages/{message_id}

Response:

{
  "status": "deleted",
  "id": "a7f3d8e9"
}

⚡ Rate Limits

API keys are limited to 100 requests per hour by default.

Need higher limits? Contact us.

🔒 Security Best Practices

Need an API Key?

API access is available for business customers. Contact our team to get started.

📦 Ready-to-Use Client Libraries

Don't want to handle encryption yourself? We've got you covered!

These open-source libraries handle all encryption automatically while maintaining zero-knowledge security.