Шаблоны и рекомендации качества
GET /api/v1/quality/recommendations
Возвращает 24 шаблона, подходящие поля доступных сайтов и сводку без создания правил.
Доступ
Bearer API-ключ активного пространства и право runs.read. Для записи нужны ключ с записью и sites.write на выбранном сайте. Общие определения изменяет только оператор платформы с settings.manage, не внешний ключ. Сайты и история ограничены текущей командой. На агенте POST/PATCH/DELETE запрещены: определения меняются в облаке.
Параметры
| Имя | Где | Обязательно | Описание |
|---|---|---|---|
site_id |
query | нет | Ограничить предложения одним доступным сайтом. Чужой сайт даёт 404. Список sites и summary остаются по всем доступным ресурсам. |
locale |
query | нет | Язык справочника, предложений и пояснений. Если не указан, учитывается cookie akmelo_locale; иначе ru. Имена полей пользователя не переводятся. |
Тело не требуется. locale=ru|en выбирает язык подписей и пояснений; без явного параметра используется cookie akmelo_locale, затем русский. Код вида и имена полей не переводятся.
Ответ 200
Пример сокращён. Числовые ID условны; полные поля описаны ниже и в скачиваемой схеме OpenAPI.
{
"presets": [],
"sites": [],
"recommendations": [],
"summary": {
"rules_count": 3,
"site_rules_count": 0,
"global_rules_count": 3,
"active_rules_count": 3,
"findings_count": 0,
"scripts_count": 1,
"can_manage_global": false,
"can_create_rules": true
},
"scan_limit": 5000
}
| Поле | Значение |
|---|---|
presets[] |
Все 24 шаблона: id, kind, category_id, category, title, description, benefit, example, image, params, action, field_role |
sites[] |
Только доступные сайты: ID, код, название, fields[] с code, name, type, is_required, is_key, число сценариев и can_manage |
recommendations[] |
Не более 200 предложений: preset_id, site_id, подходящее field, подставленные params, reason, score, used |
summary |
Число всех, общих, собственных и активных правил, находок и сценариев по доступным данным, can_manage_global, can_create_rules |
scan_limit |
Предел записей выборки проверки поля, сейчас 5000 |
availability |
Совместимость определений и отчётов с облаком: definitions и reports |
summary.site_rules_count не включает общие правила. Значения summary не зависят от фильтров таблицы интерфейса. used относится к конкретному сайту, виду и параметрам, а не запрещает повторное использование карточки. Для создания отправьте params и preset_id в POST rules. Идентификатор сайта выбирайте самостоятельно из доступных, не доверяйте одному распознанному имени поля.
В основном приложении оба значения availability равны supported. На агенте definitions=unsupported означает, что подписанный снимок не подтверждает поддержку определений качества; обновите агент/облако, локальное создание всё равно запрещено. reports=unsupported означает отсутствие согласованной поддержки отчётов, pending означает ожидающие передачи именно отчёты качества, supported означает поддержку без ожидающей очереди. pending не означает отсутствие замечаний. При недоступном облаке результаты остаются локальными до подтверждённой доставки.
Поведение и ограничения
В примере списки сокращены. Ответ содержит все 24 карточки. Предложения строятся по объявленным полям, без внешней модели. used означает совпадение существующего правила по сайту, виду и параметрам; он не запрещает другую проверку. Проверьте поле и условия перед POST. can_manage учитывает права владельца; read-only API-ключ всё равно не разрешает запись.
Числовые примеры сохраняют прежний контракт v1. Для публичных UUID используйте X-Identifier-Format: uuid либо тот же метод /api/v2. Это относится и к вложенным ссылкам на сайты, правила и сборы; preset_id, category_id и field остаются строковыми кодами. Форматы идентификаторов.
Подробные примеры всех 24 шаблонов и работа с интерфейсом: Качество данных. Схема параметров: справочник.
Как отправить запрос
В серверном окружении задайте BASE (адрес установки без завершающего слеша) и API_KEY. Секрет не вставляется в исходник. Подготовка клиентов и браузерный JavaScript.
curl
curl --fail-with-body -X GET "$BASE/api/v1/quality/recommendations?site_id=1&locale=ru" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
Node.js · сервер
// Node.js, сервер. Сохраните как request.mjs.
const response = await fetch(process.env.BASE + "/api/v1/quality/recommendations?site_id=1&locale=ru", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
Accept: "application/json"
},
signal: AbortSignal.timeout(120000)
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
console.log(await response.json());
Python
import json
import os
import urllib.request
import urllib.error
request = urllib.request.Request(
os.environ["BASE"] + "/api/v1/quality/recommendations?site_id=1&locale=ru",
method="GET",
headers={"Authorization": "Bearer " + os.environ["API_KEY"],
"Accept": "application/json"},
)
try:
with urllib.request.urlopen(request, timeout=120) as response:
print(json.load(response))
except urllib.error.HTTPError as error:
print(error.code, error.read().decode("utf-8", errors="replace"))
raise
PHP · внешний клиент
<?php
$handle = curl_init(getenv("BASE") . "/api/v1/quality/recommendations?site_id=1&locale=ru");
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("API_KEY"),
"Accept: application/json",
],
]);
$content = curl_exec($handle);
$status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
if ($content === false) {
throw new RuntimeException(curl_error($handle));
}
curl_close($handle);
if ($status < 200 || $status >= 300) {
throw new RuntimeException("HTTP $status: $content");
}
print_r(json_decode($content, true, 512, JSON_THROW_ON_ERROR));
Go
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
request, err := http.NewRequest("GET", os.Getenv("BASE") + "/api/v1/quality/recommendations?site_id=1&locale=ru", nil)
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer " + os.Getenv("API_KEY"))
request.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 120 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
content, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, content))
}
fmt.Println(string(content))
}
Если запрос не выполнен
401: проверьте ключ и срок. 403: права, режим чтения/записи и 2FA. 404: идентификатор и пространство. 422: поля запроса или состояние объекта. 429: подождите Retry-After. Подробно об ошибках и повторах.