Secure Pastebin API

Zero-Knowledge API for encrypted notes, subjects, and Markdown payloads

POST /api/pastes POST /api/pastes/{id} GET /api/pastes/{id} GET /api/pastes/{id}/meta GET /api/options GET /api/health
ℹ️
Important
Subject, Markdown text, and any password-derived key handling must stay on the client side. The API should receive only encrypted bytes and metadata like expiration and burn-after-read flags.

Base URL

https://share.plotify.shop

Supported capabilities

create custom id retrieve metadata custom expiration burn after read password flag byte arrays base64url payloads

Endpoint overview

Method Endpoint What it does
POST /api/pastes Create a new encrypted paste. The server generates a short id unless you pass one in the body.
POST /api/pastes/{id} Create a new encrypted paste with a custom short id in the URL path.
GET /api/pastes/{id} Fetch the encrypted payload plus metadata. Burn-after-read pastes are deleted after the first successful read.
GET /api/pastes/{id}/meta Read metadata only without consuming the encrypted payload.
GET /api/options Return limits, presets, supported formats, and the endpoint map.
GET /api/health Simple health check for uptime monitoring.

Legacy routes /api/create and /api/get/{id} still work for backward compatibility.

Create request body

{
  "encryptedData": {
    "iv": [12, 83, 144, 221],
    "data": [167, 44, 222, 1]
  },
  "expiresIn": 86400,
  "customExpiresAt": 0,
  "burnAfterRead": true,
  "hasPassword": true
}

Create field notes

  • encryptedData.iv and encryptedData.data can be sent as byte arrays.
  • You can also send iv/data at the top level instead of nesting under encryptedData.
  • You can send ivBase64/dataBase64 or encryptedData.ivBase64/encryptedData.dataBase64 instead of byte arrays.
  • customExpiresAt is a Unix timestamp in seconds and overrides expiresIn.
  • hasPassword is a client hint only. Never send the password itself to the API.
  • Subject and Markdown stay inside the encrypted payload so the API remains zero-knowledge.

Create example

curl -X POST https://share.plotify.shop/api/pastes \
  -H "Content-Type: application/json" \
  -d '{
    "encryptedData": {
      "iv": [12, 83, 144, 221],
      "data": [167, 44, 222, 1]
    },
    "expiresIn": 86400,
    "customExpiresAt": 0,
    "burnAfterRead": true,
    "hasPassword": true
  }'

Create with custom path ID

curl -X POST https://share.plotify.shop/api/pastes/customPasteId123 \
  -H "Content-Type: application/json" \
  -d '{
    "ivBase64": "A1Jz4Q",
    "dataBase64": "m6xK4w8t...",
    "expiresIn": 3600,
    "burnAfterRead": false,
    "hasPassword": false
  }'

Create response

{
  "success": true,
  "apiVersion": "1.2",
  "id": "customPasteId123",
  "expiresAt": 1770000000,
  "expiresIn": 3600,
  "burnAfterRead": false,
  "hasPassword": false,
  "url": "https://share.plotify.shop/p/customPasteId123",
  "retrieveUrl": "https://share.plotify.shop/api/pastes/customPasteId123",
  "metaUrl": "https://share.plotify.shop/api/pastes/customPasteId123/meta",
  "docsUrl": "https://share.plotify.shop/api/docs"
}

Read response

{
  "success": true,
  "apiVersion": "1.2",
  "id": "customPasteId123",
  "encryptedData": {
    "iv": [12, 83, 144, 221],
    "data": [167, 44, 222, 1],
    "ivBase64": "A1Jz4Q",
    "dataBase64": "m6xK4w8t..."
  },
  "data": {
    "iv": [12, 83, 144, 221],
    "data": [167, 44, 222, 1]
  },
  "burnAfterRead": false,
  "hasPassword": false,
  "created": 1769990000000,
  "expiresAt": 1770000000,
  "views": 1
}

Options response

{
  "success": true,
  "service": "Secure Pastebin API",
  "apiVersion": "1.2",
  "baseUrl": "https://share.plotify.shop",
  "docsUrl": "https://share.plotify.shop/api/docs",
  "limits": {
    "minExpirySeconds": 300,
    "maxExpirySeconds": 31536000,
    "maxEncryptedPayloadBytes": 4194304
  },
  "capabilities": [
    "create encrypted pastes",
    "create with custom id",
    "fetch encrypted pastes",
    "fetch paste metadata without consuming the payload",
    "custom expiration",
    "burn after read",
    "password-aware flag"
  ]
}

Behavior notes

  • url is the clean short-link base without the key fragment.
  • retrieveUrl is the API endpoint for programmatic reads.
  • metaUrl gives metadata without consuming the ciphertext.
  • Reading a burn-after-read paste from /api/pastes/{id} removes it after the first successful response.
  • Byte arrays and base64url are both returned on reads for easier client integration.

JavaScript example

const payload = {
  encryptedData: {
    iv: Array.from(ivBytes),
    data: Array.from(cipherBytes)
  },
  expiresIn: 86400,
  customExpiresAt: 0,
  burnAfterRead: false,
  hasPassword: false
};

const createRes = await fetch('https://share.plotify.shop/api/pastes', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload)
});

const created = await createRes.json();
const readRes = await fetch(created.retrieveUrl);
const encryptedPaste = await readRes.json();

PHP example

<?php

$payload = [
    'encryptedData' => [
        'iv' => [12, 83, 144, 221],
        'data' => [167, 44, 222, 1],
    ],
    'expiresIn' => 86400,
    'burnAfterRead' => false,
    'hasPassword' => false,
];

$ch = curl_init('https://share.plotify.shop/api/pastes');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

Typical integration flow

  1. Generate the AES key in the browser or in your app.
  2. Optionally derive the key from a password locally.
  3. Encrypt a JSON payload that contains subject and Markdown content.
  4. Send the encrypted bytes plus expiration settings to /api/pastes or /api/pastes/{id}.
  5. Share result.url#keyFragment with the recipient.
  6. The recipient calls /api/pastes/{id}, then decrypts locally.