SecureBin API

Programmatic Encrypted Pastes — Create, read, and manage zero-knowledge encrypted pastes via REST API. All encryption happens client-side. The API only handles encrypted blobs.

Authentication

Authenticate all API requests by including your API key in the Authorization header as a Bearer token.

HTTP Header
Authorization: Bearer YOUR_API_KEY

Get your API key from your account dashboard after upgrading to Pro or Team. Requests without a valid API key will return 401 Unauthorized.

Keep your API key secret. Do not expose it in client-side code, public repositories, or browser requests. Use it only from server-side applications.

Base URL

All API endpoints are relative to the following base URL:

Base URL
https://securebin.ai/api/v1

Endpoints

POST /api/v1/paste

Create a new encrypted paste. The request body must contain the pre-encrypted data blob.

Request Body

FieldTypeDescription
data requiredstringBase64-encoded encrypted data blob (AES-256-GCM ciphertext)
burnAfterReadingbooleanIf true, the paste is deleted after a single read. Default: false
expirystringExpiry duration. Values: 5m, 10m, 1h, 1d, 7d, 30d, or an ISO 8601 timestamp (Pro/Team). Default: 1d
hasPasswordbooleanIndicates the paste was encrypted with an additional password. Default: false
formatstringContent format hint. Values: plaintext, markdown, code, json. Default: plaintext

Example Request

JSON
{
  "data": "encrypted-base64-blob...",
  "burnAfterReading": false,
  "expiry": "1d",
  "hasPassword": false,
  "format": "plaintext"
}

Example Response

JSON — 201 Created
{
  "id": "aBcDeFgHiJkLmNoP",
  "expires": "2026-03-26T00:00:00Z",
  "url": "https://securebin.ai/p/aBcDeFgHiJkLmNoP"
}
GET /api/v1/paste/:id

Read an encrypted paste. Returns the encrypted data blob. If the paste has burnAfterReading enabled, it will be permanently deleted after this request.

URL Parameters

ParamTypeDescription
id requiredstringThe paste ID from the creation response

Example Response

JSON — 200 OK
{
  "id": "aBcDeFgHiJkLmNoP",
  "data": "encrypted-base64-blob...",
  "burnAfterReading": false,
  "hasPassword": false,
  "format": "plaintext",
  "created": "2026-03-25T12:00:00Z",
  "expires": "2026-03-26T00:00:00Z"
}
GET /api/v1/paste/:id/exists

Check if a paste exists without reading its content. Useful for verifying paste availability before attempting decryption. Does not trigger burn-after-reading.

Example Response

JSON — 200 OK
{
  "exists": true,
  "hasPassword": false,
  "burnAfterReading": false,
  "expires": "2026-03-26T00:00:00Z"
}
DELETE /api/v1/paste/:id

Permanently delete a paste. This action is irreversible.

Example Response

JSON — 200 OK
{
  "deleted": true,
  "id": "aBcDeFgHiJkLmNoP"
}

Code Examples

Complete examples showing how to create an encrypted paste with each language. These examples handle encryption client-side, then send the ciphertext to the API.

Bash
# Create an encrypted paste
curl -X POST https://securebin.ai/api/v1/paste \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "ENCRYPTED_BASE64_BLOB",
    "expiry": "1d",
    "burnAfterReading": false,
    "format": "plaintext"
  }'

# Read a paste
curl https://securebin.ai/api/v1/paste/aBcDeFgHiJkLmNoP \
  -H "Authorization: Bearer YOUR_API_KEY"

# Delete a paste
curl -X DELETE https://securebin.ai/api/v1/paste/aBcDeFgHiJkLmNoP \
  -H "Authorization: Bearer YOUR_API_KEY"
JavaScript (Fetch)
// Encrypt data with AES-256-GCM using Web Crypto API
async function encryptAndPaste(plaintext, apiKey) {
  // Generate a random 256-bit key
  const key = await crypto.subtle.generateKey(
    { name: 'AES-GCM', length: 256 },
    true, ['encrypt']
  );

  // Generate random IV
  const iv = crypto.getRandomValues(new Uint8Array(12));

  // Encrypt the data
  const encoded = new TextEncoder().encode(plaintext);
  const ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key, encoded
  );

  // Combine IV + ciphertext and base64-encode
  const combined = new Uint8Array(iv.length + ciphertext.byteLength);
  combined.set(iv);
  combined.set(new Uint8Array(ciphertext), iv.length);
  const blob = btoa(String.fromCharCode(...combined));

  // Send encrypted blob to API
  const res = await fetch('https://securebin.ai/api/v1/paste', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      data: blob,
      expiry: '1d',
      format: 'plaintext'
    })
  });

  const { id, url } = await res.json();

  // Export key for URL fragment
  const rawKey = await crypto.subtle.exportKey('raw', key);
  const keyB64 = btoa(String.fromCharCode(...new Uint8Array(rawKey)));

  return `${url}#${keyB64}`;
}
Python
import os, base64, json, requests
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

def encrypt_and_paste(plaintext: str, api_key: str) -> str:
    # Generate random 256-bit key and 96-bit IV
    key = os.urandom(32)
    iv = os.urandom(12)

    # Encrypt with AES-256-GCM
    aesgcm = AESGCM(key)
    ciphertext = aesgcm.encrypt(iv, plaintext.encode(), None)

    # Combine IV + ciphertext, base64-encode
    blob = base64.b64encode(iv + ciphertext).decode()

    # Send to API
    res = requests.post(
        "https://securebin.ai/api/v1/paste",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        },
        json={
            "data": blob,
            "expiry": "1d",
            "format": "plaintext",
        },
    )

    result = res.json()
    key_b64 = base64.urlsafe_b64encode(key).decode()

    return f"{result['url']}#{key_b64}"

# Usage
url = encrypt_and_paste("my secret data", "YOUR_API_KEY")
print(f"Share this URL: {url}")
Node.js
const crypto = require('crypto');

async function encryptAndPaste(plaintext, apiKey) {
  // Generate random key and IV
  const key = crypto.randomBytes(32);
  const iv = crypto.randomBytes(12);

  // Encrypt with AES-256-GCM
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  let encrypted = cipher.update(plaintext, 'utf8');
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  const authTag = cipher.getAuthTag();

  // Combine IV + ciphertext + authTag
  const combined = Buffer.concat([iv, encrypted, authTag]);
  const blob = combined.toString('base64');

  // Send to API
  const res = await fetch('https://securebin.ai/api/v1/paste', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      data: blob,
      expiry: '1d',
      format: 'plaintext',
    }),
  });

  const { url } = await res.json();
  const keyB64 = key.toString('base64url');

  return `${url}#${keyB64}`;
}

// Usage
encryptAndPaste('my secret data', 'YOUR_API_KEY')
  .then(url => console.log('Share:', url));

Encryption Guide

SecureBin uses a zero-knowledge architecture. The server never sees your plaintext data or encryption keys. Here is how the encryption flow works:

  1. Generate a random 256-bit key using a cryptographically secure random number generator (crypto.getRandomValues in browsers, os.urandom in Python, crypto.randomBytes in Node.js).
  2. Encrypt the payload with AES-256-GCM using the generated key and a random 96-bit initialization vector (IV). AES-GCM provides both confidentiality and authentication.
  3. Send the encrypted blob to the API. Combine the IV and ciphertext, base64-encode the result, and send it as the data field in your POST request. The server stores only ciphertext.
  4. Share the URL with the key in the fragment. The decryption key is appended to the URL after the # character (e.g., https://securebin.ai/p/abc123#KEY). URL fragments are never sent to the server by browsers, so the key remains client-side only.

Why this is secure: Even if the server is compromised, an attacker only obtains encrypted blobs. Without the key (which exists only in the shared URL fragment), the data is computationally impossible to decrypt.

Rate Limits

API rate limits vary by plan. Exceeding the limit returns 429 Too Many Requests with a Retry-After header.

Plan Requests / Day Max Paste Size Custom Expiry
Free Web only (no API) 10 MB Presets only
Pro 1,000 50 MB Yes (ISO 8601)
Team 10,000 100 MB Yes (ISO 8601)

Need higher limits? Contact us for enterprise plans.

SDKs

Official SDK libraries are under active development. They handle encryption, key management, and API calls so you can create secure pastes in a single function call.

securebin-js

npm package for Node.js and browsers

Coming Soon

securebin-py

pip package for Python 3.8+

Coming Soon

securebin-cli

Standalone binary for CI/CD pipelines

Coming Soon

Want early access? Email us or follow us for updates.