Complete guide to secure, ephemeral secret sharing with BurnOnRead.
BurnOnRead is a secure platform for sharing sensitive information that automatically self-destructs after being viewed. Perfect for sharing passwords, API keys, credentials, and confidential data.
/s/<secret_id>)Dropzones allow you to request secrets from others:
Integrate BurnOnRead into your applications with our REST API.
https://burnonread.com
All API responses are in JSON format.
The API uses standard HTTP status codes:
200 - Success400 - Bad Request (invalid parameters)401 - Unauthorized (invalid or missing API key)404 - Not Found (secret doesn't exist or expired)429 - Too Many Requests (rate limit exceeded)500 - Internal Server ErrorInclude your API key in the X-API-KEY header:
curl -H "X-API-KEY: sk_yourapikey123..." \
-d '{"secret_text":"my secret"}' \
https://burnonread.com/create
POST /create
Content-Type: application/json
X-API-KEY: sk_yourapikey123...
| Parameter | Type | Required | Description |
|---|---|---|---|
secret_text |
string | Yes | The secret message to encrypt and store |
password |
string | No | Optional password protection |
duration |
integer | No | Expiration time in minutes (15-60 for Pro, 15 for free). Default: 60 |
{
"secret_text": "Database password: MyS3cur3P@ss!",
"password": "optional_password",
"duration": 30
}
{
"secret_id": "abc123def456",
"link": "https://burnonread.com/s/abc123def456",
"expires_in_minutes": 30
}
{
"error": "secret_text is required"
}
curl -X POST https://burnonread.com/create \
-H "Content-Type: application/json" \
-H "X-API-KEY: sk_yourapikey123..." \
-d '{
"secret_text": "Database password: MyS3cur3P@ss!",
"password": "optional_password",
"duration": 30
}'
POST /app/dropzone
Create a secure dropzone to request secrets from others.
Content-Type: application/json
X-API-KEY: sk_yourapikey123...
| Parameter | Type | Required | Description |
|---|---|---|---|
requester_email |
string | Yes | Email of person filling the dropzone |
label |
string | Yes | Description (e.g., "Database Password") |
{
"dropzone_id": "xyz789abc123",
"link": "https://burnonread.com/d/xyz789abc123",
"label": "Database Password",
"expires_in_hours": 24
}
POST /dropzone/reveal/<dropzone_id>
Retrieve and delete the secret from a filled dropzone.
{
"secret": "The decrypted secret text",
"filled_at": "2025-01-15T14:30:00Z"
}
import requests
import json
API_KEY = "sk_yourapikey123..."
BASE_URL = "https://burnonread.com"
def create_secret(text, password=None, duration=60):
"""Create a self-destructing secret"""
headers = {
"Content-Type": "application/json",
"X-API-KEY": API_KEY
}
data = {
"secret_text": text,
"duration": duration
}
if password:
data["password"] = password
response = requests.post(
f"{BASE_URL}/create",
headers=headers,
json=data
)
if response.status_code == 200:
result = response.json()
return result["link"]
else:
raise Exception(f"Error: {response.text}")
# Usage
link = create_secret(
"Database password: MyS3cur3P@ss!",
password="optional_password",
duration=30
)
print(f"Secret link: {link}")
const axios = require('axios');
const API_KEY = 'sk_yourapikey123...';
const BASE_URL = 'https://burnonread.com';
async function createSecret(text, password = null, duration = 60) {
try {
const response = await axios.post(
`${BASE_URL}/create`,
{
secret_text: text,
password: password,
duration: duration
},
{
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
}
}
);
return response.data.link;
} catch (error) {
console.error('Error creating secret:', error.response.data);
throw error;
}
}
// Usage
createSecret('Database password: MyS3cur3P@ss!', 'optional_password', 30)
.then(link => console.log(`Secret link: ${link}`))
.catch(err => console.error(err));
<?php
$apiKey = 'sk_yourapikey123...';
$baseUrl = 'https://burnonread.com';
function createSecret($text, $password = null, $duration = 60) {
global $apiKey, $baseUrl;
$data = [
'secret_text' => $text,
'duration' => $duration
];
if ($password) {
$data['password'] = $password;
}
$ch = curl_init("$baseUrl/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"X-API-KEY: $apiKey"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
return $result['link'];
} else {
throw new Exception("Error: $response");
}
}
// Usage
$link = createSecret(
'Database password: MyS3cur3P@ss!',
'optional_password',
30
);
echo "Secret link: $link\n";
?>
#!/bin/bash
API_KEY="sk_yourapikey123..."
BASE_URL="https://burnonread.com"
# Create a secret
create_secret() {
local secret_text="$1"
local password="${2:-}"
local duration="${3:-60}"
local data="{\"secret_text\":\"$secret_text\",\"duration\":$duration"
if [ -n "$password" ]; then
data="$data,\"password\":\"$password\""
fi
data="$data}"
curl -X POST "$BASE_URL/create" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $API_KEY" \
-d "$data" \
| jq -r '.link'
}
# Usage
LINK=$(create_secret "Database password: MyS3cur3P@ss!" "optional_password" 30)
echo "Secret link: $LINK"
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
APIKey = "sk_yourapikey123..."
BaseURL = "https://burnonread.com"
)
type SecretRequest struct {
SecretText string `json:"secret_text"`
Password string `json:"password,omitempty"`
Duration int `json:"duration"`
}
type SecretResponse struct {
SecretID string `json:"secret_id"`
Link string `json:"link"`
ExpiresInMinutes int `json:"expires_in_minutes"`
}
func createSecret(text, password string, duration int) (string, error) {
req := SecretRequest{
SecretText: text,
Password: password,
Duration: duration,
}
jsonData, err := json.Marshal(req)
if err != nil {
return "", err
}
httpReq, err := http.NewRequest("POST", BaseURL+"/create", bytes.NewBuffer(jsonData))
if err != nil {
return "", err
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("X-API-KEY", APIKey)
client := &http.Client{}
resp, err := client.Do(httpReq)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != 200 {
return "", fmt.Errorf("error: %s", string(body))
}
var result SecretResponse
if err := json.Unmarshal(body, &result); err != nil {
return "", err
}
return result.Link, nil
}
func main() {
link, err := createSecret("Database password: MyS3cur3P@ss!", "optional_password", 30)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Secret link:", link)
}
BurnOnRead uses AES-256-GCM encryption to protect secrets at rest:
1. Create password-protected secret via API
2. Send link to recipient via Slack
3. Call recipient to provide password
4. Recipient views secret
5. You receive real-time notification
6. Secret is automatically deleted
Yes, anyone can create secrets via the web interface without an account. However, API access requires a Pro account (one-time $29 lifetime license).
API endpoints are rate-limited to prevent abuse. If you hit the limit, you'll receive a 429 Too Many Requests response. Wait and retry with exponential backoff.
Secrets can only be viewed once via their unique URL (/s/<secret_id>). The API is for creation, not retrieval, to maintain security.
Your old API key is immediately invalidated. Update all integrations with the new key to avoid authentication errors.
BurnOnRead is provided as a hosted service with distributed POPs in New York City, San Francisco, and Frankfurt — with more coming online as we scale.
Please email security issues to security@burnonread.com. We take security seriously and will respond promptly.
Can't find what you're looking for? Contact support or file a support request.