openonce

API

Безкоштовне, без ключів, з обмеженням частоти за IP. Шифруйте на своєму боці, а ми збережемо байти.

Базова адреса

https://api.openonce.link/api/v1
POST/secrets

Створити секрет

Повертає ідентифікатор і час завершення дії.

Запит

{
  "content": "ciphertext-or-plaintext",
  "ttl": "1d",
  "ttlSeconds": 3600,
  "views": 1,
  "password": null,
  "notifyChannel": "webhook",
  "notifyTo": "https://hooks.slack.com/services/...",
  "label": "prod db password",
  "kind": "text",
  "fileMeta": "{\"name\":\"config.env\",\"size\":2048,\"type\":\"text/plain\"}"
}

Відповідь

{
  "id": "8f3kQ2mVxL",
  "expiresAt": "2026-08-08T12:04:11.000Z",
  "views": 1,
  "hasPassword": false,
  "notifyOnRead": true
}
GET/secrets/:id/meta

Перевірити секрет

Показує, чи секрет ще живий і скільки переглядів залишилось. Перегляд при цьому не витрачається.

Відповідь

{
  "id": "8f3kQ2mVxL",
  "alive": true,
  "viewsLeft": 1,
  "viewsTotal": 2,
  "expiresAt": "2026-08-08T12:04:11.000Z",
  "hasPassword": false,
  "kind": "text"
}
POST/secrets/:id/reveal

Показати секрет

Витрачає один перегляд і повертає збережений вміст. Ця дія незворотна.

Запит

{
  "password": null
}

Відповідь

{
  "content": "ciphertext-or-plaintext",
  "viewsLeft": 0,
  "kind": "file",
  "fileMeta": "{\"name\":\"config.env\",\"size\":2048,\"type\":\"text/plain\"}"
}
DELETE/secrets/:id

Знищити секрет

Видаляє секрет до того, як його хтось прочитає.

Відповідь

{
  "destroyed": true
}

Надсилання файлів

Вкажіть kind: "file" і передайте fileMeta як JSON-рядок з name, size і type. Байти йдуть у content, як і будь-що інше — шифруйте їх самі. Зверніть увагу: fileMeta зберігається як є, тому не кладіть секрети в назву файлу.

Сповіщення про прочитання

Передайте notifyChannel і notifyTo під час створення секрету — і ми звернемось до вашого endpoint щойно його прочитають. Сам секрет у запиті не передається.

POST https://your-app.com/hook
X-Openonce-Event: secret.revealed
X-Openonce-Timestamp: 1786412651
X-Openonce-Signature: sha256=9f86d081884c7d65...

{
  "event": "secret.revealed",
  "secretId": "8f3kQ2mVxL",
  "occurredAt": "2026-08-07T17:45:47.797Z",
  "viewsLeft": 0,
  "label": "prod db password"
}
Перевірка підпису

Кожен запит містить підпис HMAC-SHA256 над timestamp.rawBody. Порівнюйте його за сталий час, перш ніж довіряти вмісту.

const expected = crypto
  .createHmac('sha256', WEBHOOK_SECRET)
  .update(`${timestamp}.${rawBody}`)
  .digest('hex');

const isValid = crypto.timingSafeEqual(
  Buffer.from(signature.replace('sha256=', '')),
  Buffer.from(expected),
);

Командний рядок

Перетворіть будь-що на посилання, не виходячи з термінала.

npx openonce "my api key" --ttl 1h --views 2

Обмеження частоти

Ліміти діють на кожну IP-адресу. Після перевищення повертається 429, доки вікно не скинеться.

Створення секретів10 за 60 с
Усі інші ендпоінти30 за 60 с

Помилки

Помилки використовують стандартні коди статусу з тілом JSON, яке містить код помилки та зрозумілий опис.

{
  "statusCode": 404,
  "error": "Not Found",
  "code": "SECRET_NOT_FOUND",
  "message": "This secret does not exist or has already been destroyed."
}
400CONTENT_TOO_LARGE
400INVALID_NOTIFICATION_TARGET
401PASSWORD_REQUIRED
401WRONG_PASSWORD
404SECRET_NOT_FOUND
429ThrottlerException