TimeLayer API: один вызов — одна квитанция
Весь API — это один HTTP-вызов. Вы локально хешируете действие или документ, отправляете только хеш и получаете самодостаточную квитанцию: пользователь держит её у себя, а проверить может любой офлайн. Ваш контент не покидает вашу машину.
Содержание
1. Две минуты до первой квитанции
- Заведите бесплатный аккаунт на cabinet.timelayer-os.com — на старте дают бесплатные квитанции.
- Скопируйте API-токен из кабинета.
- Захешируйте что угодно и заверьте:
# хеш строки (или файла: shasum -a 256 file) HASH=$(printf 'счёт #4471 одобрен alex@acme.com' | shasum -a 256 | cut -d' ' -f1) curl -X POST https://api.timelayer-os.com/v1/notarize \ -H "Authorization: Bearer $TL_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"action_hex\": \"$HASH\"}"
В ответ придут cert_hex и bundle_hex. Раскодируйте их в байты,
сохраните как .tlcert и .tlbundle — и у вас на руках проверяемая
квитанция.
2. Базовый URL и аутентификация
Базовый URL: https://api.timelayer-os.com. Каждый запрос несёт токен в заголовке:
Authorization: Bearer <ваш API-токен>
Держите токен на сервере
Токен тратит ваш баланс квитанций. Держите его в переменной окружения, никогда — в клиентском коде или публичном репозитории. Посмотреть и перевыпустить его можно в кабинете.
3. POST /v1/notarize
Единственный эндпоинт. Принимает хеш того, что вы хотите доказать, и возвращает квитанцию, заверяющую именно этот хеш.
| Поле | Значение |
|---|---|
| action_hex | Hex хеша вашего действия или документа. Обычно SHA-256; привязка алгоритмо-нейтральна (SHA-256, BLAKE3, SHA-3…). Строчный hex, без префикса 0x. |
Тело запроса:
{ "action_hex": "b557d79ce260ed0edb9e548a9b3fe417967b6174f0e9c99ea28bfa1f27561c1e" }
Отправляется только хеш. TimeLayer никогда не видит ваше действие или документ — в этом и смысл (Zero-Data): сеть заверяет отпечаток, а не содержимое.
4. Квитанция: cert + bundle
Успешный вызов возвращает две hex-строки:
{
"cert_hex": "…", // сертификат, ~415 байт после декода
"bundle_hex": "…" // доказательная часть, ~1 КБ после декода
}
Это сырые байты в hex, не текст. Раскодируйте каждую из hex и запишите байты в файл — верификатор читает именно декодированные байты:
# bash
echo "$CERT_HEX" | xxd -r -p > receipt.tlcert
echo "$BUNDLE_HEX" | xxd -r -p > receipt.tlbundle
Пара путешествует вместе с действием. Отдайте её пользователю, вложите в документ или храните в своей базе — центрального лога держать не нужно, и верить нам потом ни в чём не придётся.
5. Проверка офлайн
Любой проверяет квитанцию на своей машине, без сети и без аккаунта, открытым верификатором:
timelayer-verifier verify receipt.tlcert receipt.tlbundle # -> VALID FINAL подлинна и полна # -> UNVERIFIABLE подделка, расхождение или порча
Чтобы доказать, что квитанция про именно ваше действие, передайте ожидаемый хеш — квитанцию, валидную саму по себе, но заверяющую другое, верификатор отвергнет:
timelayer-verifier verify receipt.tlcert receipt.tlbundle --expect "$HASH"
6. Ошибки
Ошибки возвращают JSON { "error": "…" }. При любом сомнении API падает
закрыто — он никогда не вернёт полу-валидную квитанцию.
| Статус | Тело | Значение и что делать |
|---|---|---|
| 401 | (нет) | Нет заголовка Authorization. Добавьте Bearer <токен>. |
| 401 | AUTH FAIL | Токен отсутствует, неверный или отозван. Скопируйте свежий токен из кабинета. |
| 401 | NOTARIZE FAIL reason=empty_action | action_hex пуст, отсутствует или не hex. Пришлите строчный hex настоящего хеша. |
7. Python и Node
# Python (только стандартная библиотека)
import hashlib, json, urllib.request, os
h = hashlib.sha256("счёт #4471 одобрен".encode()).hexdigest()
req = urllib.request.Request(
"https://api.timelayer-os.com/v1/notarize",
data=json.dumps({"action_hex": h}).encode(),
headers={"Authorization": f"Bearer {os.environ['TL_TOKEN']}",
"Content-Type": "application/json"}, method="POST")
r = json.load(urllib.request.urlopen(req))
open("receipt.tlcert", "wb").write(bytes.fromhex(r["cert_hex"]))
open("receipt.tlbundle","wb").write(bytes.fromhex(r["bundle_hex"]))
// Node 18+ (глобальный fetch)
import { createHash } from "node:crypto";
import { writeFileSync } from "node:fs";
const hash = createHash("sha256").update("счёт #4471 одобрен").digest("hex");
const res = await fetch("https://api.timelayer-os.com/v1/notarize", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TL_TOKEN}`,
"Content-Type": "application/json" },
body: JSON.stringify({ action_hex: hash }),
});
const r = await res.json();
writeFileSync("receipt.tlcert", Buffer.from(r.cert_hex, "hex"));
writeFileSync("receipt.tlbundle", Buffer.from(r.bundle_hex, "hex"));
8. Баланс и лимиты
Каждое успешное заверение тратит одну квитанцию с баланса. Новые аккаунты стартуют с бесплатным лимитом; дальше пополняете подпиской или разовым пакетом со страницы тарифов — разовые пакеты не сгорают. Проверка квитанций всегда бесплатна и офлайн: не стоит ничего и не требует токена.
TimeLayer