Документация: REST API

REST API

REST API. Base URL: https://api.dbsend.ru/v1

Аутентификация

Все запросы требуют заголовок Authorization:

http
Authorization: Bearer <token>
Тип токенаФорматИспользование
JWTeyJhbGci...Веб-дашборд, краткосрочные сессии
API Keysqv_pk_47a5...SDK, CI/CD, скрипты (постоянный)

Auth

POST
/auth/register

Регистрация нового пользователя

POST
/auth/login

Вход по email и паролю

POST
/auth/forgot-password

Запрос сброса пароля (письмо на email)

POST
/auth/reset-password

Установка нового пароля по токену из письма

POST
/auth/magic-link

Вход по ссылке из письма

POST
/auth/logout

Завершение сессии

POST /auth/register

json
// Request
{
  "email": "user@example.com",
  "password": "securepassword123"
}

// Response 201
{
  "token": "eyJhbGci...",
  "userId": "uuid",
  "workspaceId": "uuid"
}

POST /auth/login

json
// Request
{ "email": "user@example.com", "password": "securepassword123" }

// Response 200
{ "token": "eyJhbGci...", "userId": "uuid", "workspaceId": "uuid" }

API Keys

GET
/api-keys

Список API-ключей: databaseId, lastUsedAt, expiresAt

POST
/api-keys

Создать ключ; опционально databaseId и expiresInDays (plainKey отдаётся только здесь)

DELETE
/api-keys/:id

Отозвать ключ

json
// POST /api-keys request
{
  "name": "prod-server",
  "scopes": ["backups.upload", "backups.read"],
  "databaseId": "uuid",      // опционально: ключ работает только с этой базой, для других — 403
  "expiresInDays": 90         // опционально: 1–3650
}

// Response 201
{
  "data": {
    "id": "uuid",
    "name": "production-key",
    "keyPrefix": "sqv_pk_47a5",
    "databaseId": "uuid",
    "expiresAt": "2027-01-04T00:00:00.000Z",
    "plainKey": "sqv_pk_47a5383b4f7e057975cafb...",  // только при создании!
    "createdAt": "2026-01-01T00:00:00.000Z"
  }
}
⚠️

plainKey возвращается только при создании. Сохраните его сразу — повторно получить невозможно.

Databases

GET
/databases

Список баз рабочего пространства: latestBackupAt, snapshotCount, storedBytes

POST
/databases

Создать базу

GET
/databases/:id

Одна база: latestBackupAt, snapshotCount, storedBytes

POST
/databases/:id/pause

Приостановить приём бэкапов

POST
/databases/:id/resume

Возобновить приём бэкапов

json
// POST /databases
{
  "projectId": "uuid",
  "name": "production-db",
  "engineType": "sqlite"   // sqlite | duckdb | postgresql_dump | mysql_dump | mssql_backup | onec_dt | generic_file
}

// Response 201
{
  "data": {
    "id": "uuid",
    "name": "production-db",
    "engineType": "sqlite",
    "status": "active",
    "createdAt": "2026-01-01T00:00:00Z"
  }
}

Backups

POST
/backups/upload

Прямая загрузка файла до 32 МБ (multipart/form-data)

POST
/backups/uploads/init

Начать загрузку частями (файлы больше 32 МБ); поле label опционально

PUT
/backups/uploads/:id/chunks/:n

Загрузить часть по 10 МБ (raw binary); отдельный, более высокий rate limit

POST
/backups/uploads/:id/complete

Завершить загрузку; идемпотентно — повтор после успеха вернёт ту же версию

GET
/backups/databases/:databaseId/snapshots

История версий базы (до 50): label, pinned

PATCH
/backups/snapshots/:snapshotId

Изменить метку и закрепление: { label?, pinned? }

GET
/backups/diff?v1=:id&v2=:id

Diff двух любых версий одной базы (тарифы от «Старт»)

GET
/backups/snapshots/:id/download

Получить защищённую ссылку на скачивание версии

POST /backups/upload — поля формы

ПолеТипОбязательноОписание
fileFile✅Файл БД (gzip-сжатый SDK, raw — через браузер)
databaseIdstring✅UUID базы
originalSizenumber✅Размер оригинала в байтах
checksumSha256string—SHA-256 оригинала (рекомендуется)
enginestring—Тип БД (sqlite по умолчанию): sqlite, duckdb, postgresql_dump, mysql_dump, mssql_backup, onec_dt, generic_file
labelstring—Метка версии, до 100 символов
metadataJSON string—Произвольные метаданные

Версии: дубликаты, метки, закрепление

Если SHA-256 загружаемого файла (до сжатия) совпадает с последней версией базы, новая версия не создаётся: ответ 200 с deduplicated: true и последней версией. Обычные ответы содержат deduplicated: false.

json
// POST /backups/upload — файл не изменился
{
  "deduplicated": true,
  "snapshot": { "id": "uuid", "versionNumber": 11, "label": null, "pinned": false, ... }
}

// PATCH /backups/snapshots/:snapshotId
{ "label": "до миграции 0042", "pinned": true }

// Response 200 — обновлённая версия
{ "id": "uuid", "versionNumber": 12, "label": "до миграции 0042", "pinned": true, ... }

Закреплённые версии не удаляются ротацией и не учитываются в лимите версий на базу.

Расход и лимиты

GET
/billing/usage

Текущий тариф, расход хранилища и баз, льготный период

json
// GET /billing/usage
{
  "planId": "start",
  "planName": "Старт",
  "storedBytes": 734003200,
  "storageLimitBytes": 10737418240,   // null — без лимита
  "databases": 3,
  "databasesLimit": 5,                // null — без лимита
  "maxVersionsPerDatabase": 30,
  "gracePeriodEndsAt": null,          // ISO-дата, если идёт льготный период после окончания подписки
  "subscriptionEndsAt": "2026-11-06T00:00:00.000Z"
}

Restore

POST
/backups/:id/restore

Создать задание на восстановление

GET
/restore-jobs

Список задач восстановления

GET
/restore-jobs/:jobId

Статус конкретного задания

json
// POST /backups/:id/restore
{ "targetType": "download" }

// Response 200
{
  "data": {
    "jobId": "uuid",
    "status": "completed",
    "downloadUrl": "https://...",
    "expiresInSeconds": 900,
    "filename": "data.db",
    "version": 3
  }
}

Коды ошибок

json
// Формат ошибки
{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Превышен лимит хранилища...",
    "requestId": "uuid"
  }
}
КодHTTPОписание
UNAUTHORIZED401Невалидный/просроченный/отозванный токен
FORBIDDEN403Нет прав на операцию
NOT_FOUND404Ресурс не найден
CONFLICT409Дублирование (email и т.д.)
QUOTA_EXCEEDED402Превышена квота тарифа (хранилище, версии, загрузки)
PLAN_LIMIT402Функция или лимит недоступны на текущем тарифе
PAYLOAD_TOO_LARGE413Файл больше 32 МБ для прямой загрузки — используйте загрузку частями
RATE_LIMITED429Превышен rate limit, см. Retry-After
VALIDATION_ERROR400/422Невалидные входные данные
INTERNAL_ERROR500Внутренняя ошибка сервера

Rate Limits

ScopeЛимитОкно
IP (auth маршруты)20 запросов60 секунд
Рабочее пространство (все маршруты, кроме загрузки частей)120 запросов60 секунд

Готовы попробовать?

Бесплатный тариф: 1 база, 500 МБ и 3 версии — без карты.