Документация: REST API
REST API
REST API. Base URL: https://api.dbsend.ru/v1
Аутентификация
Все запросы требуют заголовок Authorization:
Authorization: Bearer <token>| Тип токена | Формат | Использование |
|---|---|---|
| JWT | eyJhbGci... | Веб-дашборд, краткосрочные сессии |
| API Key | sqv_pk_47a5... | SDK, CI/CD, скрипты (постоянный) |
Auth
/auth/registerРегистрация нового пользователя
/auth/loginВход по email и паролю
/auth/forgot-passwordЗапрос сброса пароля (письмо на email)
/auth/reset-passwordУстановка нового пароля по токену из письма
/auth/magic-linkВход по ссылке из письма
/auth/logoutЗавершение сессии
POST /auth/register
// Request
{
"email": "user@example.com",
"password": "securepassword123"
}
// Response 201
{
"token": "eyJhbGci...",
"userId": "uuid",
"workspaceId": "uuid"
}POST /auth/login
// Request
{ "email": "user@example.com", "password": "securepassword123" }
// Response 200
{ "token": "eyJhbGci...", "userId": "uuid", "workspaceId": "uuid" }API Keys
/api-keysСписок API-ключей: databaseId, lastUsedAt, expiresAt
/api-keysСоздать ключ; опционально databaseId и expiresInDays (plainKey отдаётся только здесь)
/api-keys/:idОтозвать ключ
// 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
/databasesСписок баз рабочего пространства: latestBackupAt, snapshotCount, storedBytes
/databasesСоздать базу
/databases/:idОдна база: latestBackupAt, snapshotCount, storedBytes
/databases/:id/pauseПриостановить приём бэкапов
/databases/:id/resumeВозобновить приём бэкапов
// 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
/backups/uploadПрямая загрузка файла до 32 МБ (multipart/form-data)
/backups/uploads/initНачать загрузку частями (файлы больше 32 МБ); поле label опционально
/backups/uploads/:id/chunks/:nЗагрузить часть по 10 МБ (raw binary); отдельный, более высокий rate limit
/backups/uploads/:id/completeЗавершить загрузку; идемпотентно — повтор после успеха вернёт ту же версию
/backups/databases/:databaseId/snapshotsИстория версий базы (до 50): label, pinned
/backups/snapshots/:snapshotIdИзменить метку и закрепление: { label?, pinned? }
/backups/diff?v1=:id&v2=:idDiff двух любых версий одной базы (тарифы от «Старт»)
/backups/snapshots/:id/downloadПолучить защищённую ссылку на скачивание версии
POST /backups/upload — поля формы
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
| file | File | ✅ | Файл БД (gzip-сжатый SDK, raw — через браузер) |
| databaseId | string | ✅ | UUID базы |
| originalSize | number | ✅ | Размер оригинала в байтах |
| checksumSha256 | string | — | SHA-256 оригинала (рекомендуется) |
| engine | string | — | Тип БД (sqlite по умолчанию): sqlite, duckdb, postgresql_dump, mysql_dump, mssql_backup, onec_dt, generic_file |
| label | string | — | Метка версии, до 100 символов |
| metadata | JSON string | — | Произвольные метаданные |
Версии: дубликаты, метки, закрепление
Если SHA-256 загружаемого файла (до сжатия) совпадает с последней версией базы, новая версия не создаётся: ответ 200 с deduplicated: true и последней версией. Обычные ответы содержат deduplicated: false.
// 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, ... }Закреплённые версии не удаляются ротацией и не учитываются в лимите версий на базу.
Расход и лимиты
/billing/usageТекущий тариф, расход хранилища и баз, льготный период
// 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
/backups/:id/restoreСоздать задание на восстановление
/restore-jobsСписок задач восстановления
/restore-jobs/:jobIdСтатус конкретного задания
// POST /backups/:id/restore
{ "targetType": "download" }
// Response 200
{
"data": {
"jobId": "uuid",
"status": "completed",
"downloadUrl": "https://...",
"expiresInSeconds": 900,
"filename": "data.db",
"version": 3
}
}Коды ошибок
// Формат ошибки
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "Превышен лимит хранилища...",
"requestId": "uuid"
}
}| Код | HTTP | Описание |
|---|---|---|
| UNAUTHORIZED | 401 | Невалидный/просроченный/отозванный токен |
| FORBIDDEN | 403 | Нет прав на операцию |
| NOT_FOUND | 404 | Ресурс не найден |
| CONFLICT | 409 | Дублирование (email и т.д.) |
| QUOTA_EXCEEDED | 402 | Превышена квота тарифа (хранилище, версии, загрузки) |
| PLAN_LIMIT | 402 | Функция или лимит недоступны на текущем тарифе |
| PAYLOAD_TOO_LARGE | 413 | Файл больше 32 МБ для прямой загрузки — используйте загрузку частями |
| RATE_LIMITED | 429 | Превышен rate limit, см. Retry-After |
| VALIDATION_ERROR | 400/422 | Невалидные входные данные |
| INTERNAL_ERROR | 500 | Внутренняя ошибка сервера |
Rate Limits
| Scope | Лимит | Окно |
|---|---|---|
| IP (auth маршруты) | 20 запросов | 60 секунд |
| Рабочее пространство (все маршруты, кроме загрузки частей) | 120 запросов | 60 секунд |
Готовы попробовать?
Бесплатный тариф: 1 база, 500 МБ и 3 версии — без карты.