Rychlý start

Pošlete text, dostanete zpět dva odkazy: jeden pro příjemce a jeden pro sebe. Base URL je onetime.fortion.cloud, všechny endpointy jsou pod /api/v1.

curl -s https://onetime.fortion.cloud/api/v1/secret \
  -H 'content-type: application/json' \
  -d '{"secret":"hunter2","ttl_days":7}'
Odpověď obsahuje klíč jen jednou — v secret_url za znakem #. Nikde ho neukládáme, takže si ho uložte vy.

Vytvoření odkazu

POST /api/v1/secret

Tělo je JSON. Povinný je jen secret; ttl_days je 1 až 30 (výchozí 14) a passphrase je volitelné dodatečné heslo.

{
  "secret": "hunter2",
  "ttl_days": 14,
  "passphrase": ""
}

// 201 Created
{
  "secret_url": "https://onetime.fortion.cloud/s/7Kq2…#Xf9…",
  "receipt_url": "https://onetime.fortion.cloud/m/3Bd1…#Qa2…",
  "kind": "text",
  "size": 7,
  "has_passphrase": false,
  "expires_at": "2026-09-09T12:00:00Z",
  "receipt_expires_at": "2026-09-16T12:00:00Z",
  "ttl_days": 14
}

Soubor

POST /api/v1/secret/file

Soubor se posílá jako multipart/form-data. Pole file musí být poslední — server čte metadata dřív, než začne streamovat obsah na disk, a nechce kvůli tomu držet celý soubor v paměti.

curl -s https://onetime.fortion.cloud/api/v1/secret/file \
  -F 'ttl_days=7' \
  -F 'passphrase=' \
  -F 'file=@report.pdf'   # must be the last field

Generování hesla

POST /api/v1/generate

Server heslo vyrobí sám a rovnou z něj udělá odkaz. Parametr alphabet je letters, alphanumeric nebo symbols, length 8 až 128. S return_value: false se heslo do odpovědi vůbec nedostane.

{
  "length": 24,
  "alphabet": "symbols",
  "ttl_days": 14,
  "return_value": false
}

// 201 Created — "value" stays null unless return_value is true
{ "secret_url": "…", "receipt_url": "…", "value": null }

Přečtení

POST /api/v1/peek

POST /api/v1/reveal

GET /api/v1/download

Nejdřív peek: zjistí typ, velikost a jestli je potřeba heslo, a obsah přitom nespálí. Teprve reveal s confirm: true obsah vydá a smaže. U souboru vrací lístek, se kterým se do pěti minut stáhne obsah z /api/v1/download.

// the key is the part of the link after the #
POST /api/v1/peek     { "key": "Xf9…" }
// 200 { "kind": "text", "state": "new", "has_passphrase": false, "size": 7 }

POST /api/v1/reveal   { "key": "Xf9…", "confirm": true }
// 200 { "kind": "text", "value": "hunter2", "revealed_at": "…" }

// files answer with a ticket instead of a body
// 200 { "download_url": "/api/v1/download", "download_ticket": "…", "ticket_expires_in": 300 }
GET /api/v1/download
X-Onetime-Ticket: "…"

Stav

POST /api/v1/receipt

Účtenka řekne, v jakém stavu odkaz je a kdy se s ním co stalo. O příjemci nevrací nic než časy.

{ "key": "Qa2…" }

// 200 — state is new | consumed | burned | destroyed | expired
{
  "state": "new",
  "kind": "text",
  "size": 7,
  "has_passphrase": false,
  "created_at": "2026-08-26T12:00:00Z",
  "secret_expires_at": "2026-09-09T12:00:00Z",
  "peeked_at": null,
  "consumed_at": null,
  "passphrase_failures": 0,
  "receipt_expires_at": "2026-09-16T12:00:00Z"
}

Smazání

POST /api/v1/receipt/burn

Dokud odkaz nikdo nepřečetl, můžete obsah zničit. Zpátky to nejde.

{ "key": "Qa2…", "confirm": true }

Chyby

Chyby jsou application/problem+json podle RFC 9457. Rozhodujte se podle pole code, ne podle textu — ten se mění a je přeložený.

// 410 Gone — content-type: application/problem+json
{
  "code": "already_revealed",
  "title": "Already revealed",
  "detail": "This link has already been used."
}
code HTTP Kdy nastane
not_found404Takový odkaz neznáme.
already_revealed409, 410Obsah už byl přečtený a tím se smazal.
burned410Odesílatel odkaz zrušil.
destroyed410Obsah byl smazaný po opakovaně špatném heslu.
passphrase_required401Odkaz je chráněný heslem.
bad_passphrase403Heslo nesedí.
too_many_attempts429Vyčerpali jste pokusy a obsah je smazaný.
confirmation_required400Potvrďte zobrazení obsahu.
payload_too_large413Obsah je moc velký.
empty400Vložte obsah, který chcete poslat.
storage_full507Došlo nám místo. Zkuste to za chvíli.
files_disabled403Posílání souborů je teď vypnuté.
read_only503Právě probíhá údržba. Nové odkazy teď nejdou vytvořit.
quota_exceeded429Z vaší sítě jde moc odkazů. Zkuste to za chvíli.
ticket_expired410Odkaz na stažení vypršel. Načtěte stránku znovu.
invalid_ttl400Platnost musí být 1 až 30 dní.
rate_limited429Moment — z vaší sítě chodí hodně požadavků. Zkuste to za minutu.
internal500Něco se nám rozbilo. Zkuste to prosím za chvíli znovu.

Limity

Ve výchozím nastavení text do 1 MB, soubor do 50 MB a platnost 1 až 30 dní; přesné hodnoty ukazuje formulář. Pět špatných pokusů o heslo obsah zničí. Rate limit je na IP a vrací 429 s hlavičkou Retry-After.

Pro AI agenty

Když má agent předat heslo člověku, doporučujeme POST /api/v1/generate s return_value: false. Heslo vyrobí server, agent dostane jen odkaz — heslo se tedy nikdy nedostane do jeho kontextu, do logu ani do historie konverzace.

curl -s https://onetime.fortion.cloud/api/v1/generate \
  -H 'content-type: application/json' \
  -d '{"length":24,"alphabet":"symbols","return_value":false}' \
  | jq -r '.secret_url'
# the generated password never passes through the agent

Strojově čitelný popis služby je na /llms.txt.

Poctivá poznámka — Šifrování probíhá na serveru. Klíč je součástí odkazu a hned ho zahazujeme — v databázi je obsah bez odkazu nečitelný.