# Award SRR API v1

Базовый URL:

```text
https://award.srr.ru/api/v1
```

## Авторизация

Основной вариант:

```http
Authorization: Bearer API_KEY
```

Совместимый вариант:

```text
?api_key=API_KEY
```

API key генерируется в личном кабинете пользователя.

## GET /me

Проверяет ключ и возвращает пользователя, его подтвержденные позывные и делегированные позывные QSL-менеджера.

```bash
curl -H "Authorization: Bearer API_KEY" \
  https://award.srr.ru/api/v1/me
```

## GET /info

Возвращает справочники:

- `bands` - диапазоны `ht_band`;
- `modes` - основные режимы `ht_mode`, связанные `ht_mode_raw` и `ht_modesub_raw`;
- `band_modes` - режимы по диапазонам `ht_band_mode`;
- `dxcc` - DXCC;
- `rda` - районы RDA;
- `regions` - регионы России;
- `r150s` - территории Р-150-С.

```bash
curl -H "Authorization: Bearer API_KEY" \
  https://award.srr.ru/api/v1/info
```

Ответ можно кэшировать на стороне логгера. В ответе есть `cache_ttl`.

## POST /qso

Принимает одно QSO или пачку QSO. Максимум 100 QSO за запрос.

Успешно обработанные строки удаляются из `ht_api_qso_inbox`. Ошибочные остаются в inbox со статусом ошибки.

Позывные `station_callsign` и `call` должны содержать только латинские буквы, цифры и `/` между непустыми частями.

Минимальный пример:

```bash
curl -X POST https://award.srr.ru/api/v1/qso \
  -H "Authorization: Bearer API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "logger": {"name": "LogHX", "version": "12.34"},
    "qsos": [
      {
        "station_callsign": "R1ABC/P",
        "call": "RA3XYZ",
        "qso_date": "2026-05-17",
        "time_on": "12:34:00",
        "band": "20M",
        "mode": "SSB",
        "sat_name": "",
        "freq": "14.250",
        "rst_sent": "59",
        "rst_rcvd": "59",
        "my_cnty": "MO-01",
        "my_gridsquare": "KO85"
      }
    ]
  }'
```

Поля можно передавать как в нижнем регистре, так и ADIF-именами:

```json
{
  "STATION_CALLSIGN": "R1ABC/P",
  "CALL": "RA3XYZ",
  "QSO_DATE": "20260517",
  "TIME_ON": "123400",
  "BAND": "20M",
  "MODE": "SSB",
  "SAT_NAME": "QO-100",
  "MY_CNTY": "MO-01"
}
```

Для удаления QSO:

```json
{
  "logger": {"name": "LogHX", "version": "12.34"},
  "qsos": [
    {
      "action": "delete",
      "station_callsign": "R1ABC/P",
      "call": "RA3XYZ",
      "qso_date": "2026-05-17",
      "time_on": "12:34",
      "band": "20M",
      "mode": "SSB"
    }
  ]
}
```

Поиск существующего QSO для обновления/удаления выполняется внутри дневного `ht_log` по:

```text
id_operator1 + id_operator2 + id_mode + id_band + datetime до минут
```

Дневной `ht_log` создается/находится по:

```text
id_user + id_log_source(API_ONLINE) + crc_summ
```

где:

```text
crc_summ = md5(id_user + дата QSO + logger_name + logger_version + API_ONLINE)
```

## POST /qso/uploadADIF

Загружает ADIF-файл так же, как форма загрузки ADIF в личном кабинете.

В ADIF поле `CALL` в каждом QSO должно содержать только латинские буквы, цифры и `/` между непустыми частями.
Если в ADIF есть поле `SAT_NAME`, оно сохраняется в строке QSO и затем возвращается при экспорте.

Поле файла в `multipart/form-data`:

- `adif` - ADIF-файл, максимум 50 MB.

Параметры формы аналогичны пользовательской форме:

- `callsign_source` - `manual` или `adif`;
- `locator_source` - `manual` или `adif`;
- `rda_source` - `manual`, `adif` или `none`;
- `manual_callsign`, `manual_callsign_suffix`, `manual_operator`;
- `manual_locator`, `manual_rda`;
- `resolved_callsign`, `resolved_operator`, `resolved_locator`, `resolved_rda`;
- `id_userOwner`, `id_user_delegate` - для загрузки QSL-менеджером по делегированному доступу;
- `logger_name`, `logger_version` - короткое имя и версия логгера.


Пример:

```bash
curl -X POST https://award.srr.ru/api/v1/qso/uploadADIF \
  -H "Authorization: Bearer API_KEY" \
  -F "logger_name=LogHX" \
  -F "logger_version=12.34" \
  -F "callsign_source=manual" \
  -F "locator_source=manual" \
  -F "rda_source=manual" \
  -F "manual_callsign=R1ABC" \
  -F "manual_locator=KO85" \
  -F "manual_rda=MO-01" \
  -F "resolved_callsign=R1ABC" \
  -F "resolved_locator=KO85" \
  -F "resolved_rda=MO-01" \
  -F "adif=@log.adi"
```

Если `callsign_source=adif`, позывной берется штатным ADIF-парсером из файла, а в `resolved_callsign` нужно передать предварительно определенный/проверенный позывной, как это делает браузерная форма.

## POST /spot

Принимает строки DIGI-эфира от программ, которые хотят передавать споты на платформу SRR. Метод аналогичен старому `recieve-digi2.php`, но использует стандартную авторизацию API:

```text
Authorization: Bearer API_KEY
```

Сервер сохраняет пакет и сразу отвечает `ACCEPTED`, а разбор строк и обновление слотов выполняет после ответа.

```bash
curl -X POST https://award.srr.ru/api/v1/spot \
  -H "Authorization: Bearer API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "station": "DESKTOP-HOME",
    "file": "C:\\MSHV\\AllTxtMonthly\\ALL_2026_05.TXT",
    "logger": {"name": "LogHX", "version": "1.0"},
    "context": {"mode": "FT8", "freq_mhz": 14.074},
    "text": "20260518_121500 -12 0.3 1445 ~ CQ R3ABC KO85\n"
  }'
```

Также можно передать строки массивом:

```json
{
  "station": "DESKTOP-HOME",
  "file": "ALL_2026_05.TXT",
  "lines": [
    "20260518_121500 -12 0.3 1445 ~ CQ R3ABC KO85",
    "20260518_121515 -10 0.2 1500 ~ R3ABC R2XYZ -05"
  ]
}
```

Ограничения первой версии: максимум 1000 непустых строк и 1 MB данных за один запрос.

## POST /qso/process

Повторно обрабатывает оставшиеся строки inbox текущего API key. Обычно не нужен логгеру, но полезен для диагностики.

```bash
curl -X POST -H "Authorization: Bearer API_KEY" \
  "https://award.srr.ru/api/v1/qso/process?limit=100"
```

## GET /qso/export

Выгружает QSO в ADIF по позывному и периоду.

```bash
curl -L -H "Authorization: Bearer API_KEY" \
  "https://award.srr.ru/api/v1/qso/export?callsign=R1ABC&from=2026-05-01&to=2026-05-17&source=all" \
  -o r1abc.adi
```

Параметры:

- `callsign` - свой или делегированный позывной;
- `from`, `to` - даты в формате `YYYY-MM-DD` или `YYYYMMDD`;
- `qsl_from`, `qsl_to` - даты подтверждения CFM/QSL в формате `YYYY-MM-DD` или `YYYYMMDD`; если указан хотя бы один из этих параметров, выгружаются только подтвержденные QSO;
- `qslsince` - короткий алиас для `qsl_from`, по смыслу аналогичен LoTW;
- `source=all` - ADIF и API_ONLINE;
- `source=api_online` - только онлайн API;
- `source=8` - конкретный `id_log_source`.

## Ответ POST /qso

```json
{
  "result": "OK",
  "accepted": 1,
  "validation_errors": [],
  "process": {
    "result": "OK",
    "processed": 1,
    "deleted": 1,
    "errors": []
  }
}
```

`result = PARTIAL` означает, что часть QSO принята или обработана с ошибками.
