# Справочник API

> API кабинета провайдера для панелей и ботов — ключи, домены, ограниченные ссылки, сообщения, устройства и статистика, с примерами curl.

Для панелей и ботов: всё, что есть в кабинете, кроме ключей API и удаления кабинета.

- Адрес: `https://api.flowlock.cc`.
- **Ключ API** — кабинет → «Ключи API» → «Создать ключ». Ключ (`flp_…`) показывается один раз; храните его как
  пароль. Ключей можно сделать до 10 и отозвать любой.
- Ключ передаётся **только в заголовке**: `Authorization: Bearer flp_…`. В адресе ключ не принимается.
- Тела и ответы — JSON, даты — RFC 3339 UTC. Ошибка — HTTP-код и `{"error": "…", "code": "…"}`. На `429` —
  заголовок `Retry-After` (секунды).
- Списки — частями: `?cursor=` из `next_cursor` прошлого ответа.
- Не больше 120 запросов в минуту.

В примерах ключ лежит в переменной окружения:

```sh
export FLOWLOCK_KEY='flp_…'
```

## Провайдер

```sh
curl -s https://api.flowlock.cc/v1/provider -H "Authorization: Bearer $FLOWLOCK_KEY"
```

```json
{
	"id": "k7m2x9q4bd",
	"name": "Мой VPN",
	"support_url": "https://t.me/myvpn_support",
	"email": "help@myvpn.example",
	"telegram": "myvpn_bot",
	"status": "active",
	"created_at": "2026-10-28T12:00:00Z",
	"limits": { "domains": 50, "…": 0 }
}
```

Изменить контакты (пустая строка удаляет поле, кроме `name`):

```sh
curl -s -X PATCH https://api.flowlock.cc/v1/provider -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{"support_url": "https://t.me/myvpn_support", "telegram": "@myvpn_bot"}'
```

Поля: `name` — 1–40 символов; `support_url` — `https://…` или `tg://…`, до 512; `email`; `telegram` — `@имя`,
ссылка `t.me` или имя (5–32 символа `A–Z a–z 0–9 _`).

## Домены

```sh
# список
curl -s https://api.flowlock.cc/v1/provider/domains -H "Authorization: Bearer $FLOWLOCK_KEY"
# добавить — в ответе запись и файл для подтверждения
curl -s -X POST https://api.flowlock.cc/v1/provider/domains -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{"domain": "sub.example.com"}'
```

```json
{
	"id": "d1f2a3b4c5d6e7f8",
	"domain": "sub.example.com",
	"hash": "…64 hex…",
	"status": "pending",
	"created_at": "…",
	"dns": {
		"name": "_flowlock.sub.example.com",
		"type": "TXT",
		"value": "flowlock-provider=k7m2x9q4bd"
	},
	"file": {
		"url": "https://sub.example.com/.well-known/flowlock-provider",
		"body": "flowlock-provider=k7m2x9q4bd"
	}
}
```

```sh
# проверить сейчас (до 20 раз в час)
curl -s -X POST https://api.flowlock.cc/v1/provider/domains/d1f2a3b4c5d6e7f8/verify -H "Authorization: Bearer $FLOWLOCK_KEY"
# удалить
curl -s -X DELETE https://api.flowlock.cc/v1/provider/domains/d1f2a3b4c5d6e7f8 -H "Authorization: Bearer $FLOWLOCK_KEY"
```

Поля домена: `status` (`pending` | `verified` | `failing` | `lost`), `method` (`dns` | `file` — чем
подтвердился), `verified_at`, `checked_at`, `error` — причина последней неудачи: `no_record` (нет записи и
файла), `wrong_id` (запись есть, ID другой), `dns_error`, `http_status`, `fetch_error`, `not_public` (домен
смотрит на частный адрес).

## Ссылки

```sh
# создать ограниченную ссылку на 3 устройства
curl -s -X POST https://api.flowlock.cc/v1/provider/installs -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://sub.example.com/abc123", "limit": 3, "note": "user 1042"}'
```

```json
{
	"id": "i8c7b6a5d4e3f2a1",
	"code": "a7k2m9x4q8b3n6p5",
	"link": "flowlock://install/a7k2m9x4q8b3n6p5",
	"web_link": "https://flowlock.cc/i/a7k2m9x4q8b3n6p5",
	"url": "https://sub.example.com/abc123",
	"domain": "sub.example.com",
	"limit": 3,
	"count": 0,
	"hwid": "",
	"note": "user 1042",
	"status": "active",
	"created_at": "…",
	"expires_at": null
}
```

```sh
# HWID-ссылка: лимит 1 и HWID устройства
curl -s -X POST https://api.flowlock.cc/v1/provider/installs -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://sub.example.com/abc123", "limit": 1, "hwid": "5f0c…"}'
# список; одна ссылка; изменить лимит, заметку, статус (active | disabled), адрес, срок
curl -s https://api.flowlock.cc/v1/provider/installs -H "Authorization: Bearer $FLOWLOCK_KEY"
curl -s https://api.flowlock.cc/v1/provider/installs/i8c7b6a5d4e3f2a1 -H "Authorization: Bearer $FLOWLOCK_KEY"
curl -s -X PATCH https://api.flowlock.cc/v1/provider/installs/i8c7b6a5d4e3f2a1 -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{"limit": 5}'
# устройства ссылки и отвязка одного
curl -s https://api.flowlock.cc/v1/provider/installs/i8c7b6a5d4e3f2a1/devices -H "Authorization: Bearer $FLOWLOCK_KEY"
curl -s -X DELETE https://api.flowlock.cc/v1/provider/installs/i8c7b6a5d4e3f2a1/devices/5f0c… \
  -H "Authorization: Bearer $FLOWLOCK_KEY"
# удалить ссылку
curl -s -X DELETE https://api.flowlock.cc/v1/provider/installs/i8c7b6a5d4e3f2a1 -H "Authorization: Bearer $FLOWLOCK_KEY"
```

`expires_at` — RFC 3339 в будущем или `null` (бессрочно). Ошибки: адрес не на подтверждённом домене —
`422 domain_unverified`; лимит меньше числа устройств — `422 limit_below_count`; с `hwid` лимит может быть только
1 — `400 bad_request`.

## Сообщения

```sh
# уведомление всем
curl -s -X POST https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{
  "kind": "notification", "mode": "optional",
  "title": "Плановые работы", "body": "Сегодня с 02:00 до 03:00 МСК возможны перебои.",
  "link": "https://myvpn.example/status",
  "locales": {"en": {"title": "Maintenance", "body": "Tonight 23:00–00:00 UTC service may be interrupted."}},
  "target": {"all": true}, "expires_in": 86400}'
```

```json
{ "id": "m3k9q2x7a1b4c5d6", "kind": "notification", "status": "active", "…": "…" }
```

```sh
# команда: обновить подписку на Windows и Linux по расписанию
curl -s -X POST https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{
  "kind": "command", "action": "update-subscription",
  "target": {"os": ["windows", "linux"]}, "send_at": "2026-11-01T09:00:00Z"}'
# команда: переезд на новый домен (должен быть подтверждён)
curl -s -X POST https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{
  "kind": "command", "action": "sub-change", "change_type": "domain", "value": "sub2.example.com",
  "target": {"all": true}}'
# команда: новые настройки двум устройствам
curl -s -X POST https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{
  "kind": "command", "action": "set-settings",
  "settings": {"ping-type": "tcp", "fragmentation-enable": true},
  "target": {"devices": ["5f0c…", "9b1e…"]}}'
# команда: предложить импорт (пользователь подтвердит)
curl -s -X POST https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY" \
  -H 'Content-Type: application/json' -d '{
  "kind": "command", "action": "import-data", "data": "https://sub.example.com/abc123",
  "target": {"devices": ["5f0c…"]}}'
# список (с итогами доставки), одно сообщение, отмена
curl -s https://api.flowlock.cc/v1/provider/messages -H "Authorization: Bearer $FLOWLOCK_KEY"
curl -s https://api.flowlock.cc/v1/provider/messages/m3k9q2x7a1b4c5d6 -H "Authorization: Bearer $FLOWLOCK_KEY"
curl -s -X DELETE https://api.flowlock.cc/v1/provider/messages/m3k9q2x7a1b4c5d6 -H "Authorization: Bearer $FLOWLOCK_KEY"
```

Поля сообщения:

- `kind` — `notification` | `command`;
- уведомление — `title`, `body`, `link`, `locales` (`ru`/`en`), `mode` (`optional` | `force`);
- команда — `action` и её поля: `change_type` + `value` (`sub-change`), `data` (`import-data`, до 16 КБ),
  `settings` (`set-settings`, ключи из [«Настроек приложения»](https://flowlock.cc/docs/app-management.md#настройки-приложения));
- `target` — `{"all": true}`, `{"os": […]}` или `{"devices": […]}`;
- `send_at` — необязательно; `expires_in` — секунды от `send_at` (3600…2592000, по умолчанию 604800).

В списке: `status` (`scheduled` | `active` | `expired` | `cancelled`) и `counts` — `received`, `shown`, `opened`,
`done`, `declined`, `failed`.

Ошибки: `400 bad_request` (поле в `field`), `422 domain_unverified`, `422 bad_setting` (ключ в `key`),
`429 rate_limited` (антиспам, `retry_after`), `403 suspended`.

## Устройства и статистика

```sh
# устройства (для выбора адресатов): фильтр по системе и активным за 30 дней
curl -s 'https://api.flowlock.cc/v1/provider/devices?os=windows&active=30d' -H "Authorization: Bearer $FLOWLOCK_KEY"
```

```json
{
	"devices": [
		{
			"device": "5f0c…",
			"device_kind": "hwid",
			"os": "windows",
			"os_version": "10.0.26200",
			"app": "0.4.0",
			"first_seen": "…",
			"last_seen": "…"
		}
	],
	"next_cursor": "…"
}
```

`device_kind`: `hwid` — HWID устройства (тот же, что приходит вашей панели в `x-hwid`); `alias` — псевдоним, если
пользователь не отправляет HWID. Подробнее — на странице [«Статистика»](https://flowlock.cc/docs/stats.md).

```sh
curl -s https://api.flowlock.cc/v1/provider/stats -H "Authorization: Bearer $FLOWLOCK_KEY"
```

```json
{
	"devices": {
		"total": 1520,
		"active_30d": 1204,
		"by_os": {
			"windows": { "total": 900, "active_30d": 700 },
			"macos": { "total": 420, "active_30d": 350 },
			"linux": { "total": 200, "active_30d": 154 }
		}
	},
	"months": [
		{
			"month": "2026-10",
			"new": { "windows": 120, "macos": 40 },
			"active": { "windows": 700, "macos": 350 }
		}
	]
}
```

## Справка для форм

`GET /v1/provider/settings-keys` — ключи «Настроек приложения» с типами (`bool`, `int`, `string`, `enum` +
`values`), областью (`app` — всё приложение, `subscription` — эта подписка) и платформами.

## Коды ошибок

| code                  | HTTP | что значит                                                                        |
| --------------------- | ---- | --------------------------------------------------------------------------------- |
| `unauthorized`        | 401  | нет ключа, ключ неверный или отозван                                              |
| `not_provider`        | 404  | у аккаунта не включён кабинет                                                     |
| `feature_disabled`    | 403  | кабинеты провайдеров временно выключены на сервере                                |
| `suspended`           | 403  | кабинет приостановлен: рассылки и новые ссылки запрещены                          |
| `bad_request`         | 400  | тело не по форме (`field` — какое поле)                                           |
| `bad_domain`          | 400  | не домен (IP, без точки, недопустимые символы)                                    |
| `conflict`            | 409  | уже есть                                                                          |
| `not_found`           | 404  | нет такого                                                                        |
| `domain_unverified`   | 422  | адрес не на вашем подтверждённом домене                                           |
| `bad_setting`         | 422  | ключа нет в списке настроек или значение не подходит (`key`)                      |
| `limit_below_count`   | 422  | лимит ссылки меньше числа её устройств                                            |
| `limit`               | 422  | потолок: доменов, ссылок, ключей, сообщений (`upgrade: true` — снимает «Анлимит») |
| `billing_off`         | 503  | оплата «Анлимита» на сервере выключена                                            |
| `prepaid_max`         | 409  | «Анлимит» уже оплачен на 12 месяцев вперёд                                        |
| `payment_unavailable` | 502  | касса не ответила, повторить позже                                                |
| `rate_limited`        | 429  | слишком часто, повторить через `retry_after`                                      |

## Лимиты

| Что                         | Сколько                             |
| --------------------------- | ----------------------------------- |
| ключей API                  | 10                                  |
| доменов                     | 50                                  |
| ограниченных ссылок         | 5000                                |
| лимит одной ссылки          | 1000 устройств                      |
| устройств в статистике      | 500 000                             |
| рассылок всем / по системам | 2 в сутки, не чаще раза в 5 минут   |
| выборочных сообщений        | 200 в час, до 20 устройств в каждом |
| ждущих сообщений            | 500                                 |
| запросов API                | 120 в минуту                        |
| ручных проверок доменов     | 20 в час                            |

Нужно больше — [«Анлимит»](https://flowlock.cc/docs/limits.md) или поддержка FlowLock.
