Кабинет
API

#Чтение

#Перечень справочников

curl -H "Authorization: Bearer КЛЮЧ" \
     https://ваш-сайт.ru/api/v1/lists/
{"ok": true, "lists": [{"id": 4, "name": "blog", "title": "Записи блога"}]}

id — то, что подставляется в остальные адреса. name — имя таблицы, title — название, видимое в панели.

#Поля справочника

curl -H "Authorization: Bearer КЛЮЧ" \
     https://ваш-сайт.ru/api/v1/lists/4/fields/
{
  "ok": true,
  "list": 4,
  "fields": [
    {"name": "title",   "title": "Заголовок", "type": "string"},
    {"name": "content", "title": "Текст",     "type": "text"}
  ]
}

Смотреть поля стоит до первой записи: писать можно только в объявленные.

#Поля-связки

Поле «выбор» или «флажки» хранит номер строки другого справочника, а поле «картинка» — номер файла медиатеки. На какой справочник смотрит поле, сказано прямо в ответе:

{
  "name": "rubrika", "title": "Рубрика", "type": "select",
  "links_to": {
    "list": 9, "name": "rubriki", "title": "Рубрики",
    "value": "id", "label": "name"
  }
}
КлючЧто значит
list, name, titleномер, имя и название целевого справочника
valueчто кладётся в поле — обычно id
labelкакое поле цели показывается человеку

У картинок связка другая:

{"name": "cover", "type": "image",
 "links_to": {"media": true, "hint": "номер файла из /api/v1/media/"}}
Важно

Не угадывайте целевой справочник по имени поля. «Поле category — значит справочник category» верно на одном сайте и неверно на соседнем: имена справочников задаёт владелец. Спросите /fields/.

#Записи

curl -H "Authorization: Bearer КЛЮЧ" \
     "https://ваш-сайт.ru/api/v1/lists/4/records/?limit=20&offset=0"
<?php
$url = 'https://ваш-сайт.ru/api/v1/lists/4/records/?'
     . http_build_query(['limit' => 20, 'offset' => 0]);

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer КЛЮЧ'],
]);
$answer = json_decode(curl_exec($ch), true);
curl_close($ch);

echo 'всего записей: ', $answer['count'], PHP_EOL;
import requests

r = requests.get(
    'https://ваш-сайт.ru/api/v1/lists/4/records/',
    params={'limit': 20, 'offset': 0},
    headers={'Authorization': 'Bearer КЛЮЧ'},
    timeout=15,
)
answer = r.json()
print('всего записей:', answer['count'])
const url = new URL('https://ваш-сайт.ru/api/v1/lists/4/records/');
url.searchParams.set('limit', '20');
url.searchParams.set('offset', '0');

const res = await fetch(url, {
  headers: { Authorization: 'Bearer КЛЮЧ' },
});
const answer = await res.json();
console.log('всего записей:', answer.count);
{
  "ok": true,
  "list": 4,
  "count": 137,
  "limit": 20,
  "offset": 0,
  "records": [{"id": 137, "title": "…"}]
}

count — сколько записей всего, а не сколько пришло. По нему считаются страницы.

ПараметрЧто задаётПо умолчанию
limitсколько записей отдать50, больше 500 нельзя
offsetсколько пропустить0
orderByполе сортировкиid
orderasc или descdesc
published1 — только опубликованноеотдаётся всё
Почему так

По умолчанию отдаётся всё, включая черновики и запланированное.

API — это управление, а не витрина. Кому нужна витрина, тот просит published=1 и получает ровно то, что видит посетитель сайта.

Важно

Запись с датой публикации в будущем на сайте не показывается, пока не наступит время, — часы при этом считаются по UTC, а не по местному поясу. Разница видна как раз на записях, поставленных «на сегодня вечером».

#Одна запись

curl -H "Authorization: Bearer КЛЮЧ" \
     https://ваш-сайт.ru/api/v1/lists/4/records/137/
{"ok": true, "record": {"id": 137, "title": "…"}}

Записи нет — 404 и {"ok": false, "error": "Записи нет."}.

#Как пройти справочник целиком

offset=0
while :; do
  curl -s -H "Authorization: Bearer КЛЮЧ" \
       "https://ваш-сайт.ru/api/v1/lists/4/records/?limit=500&offset=$offset" \
       > page.json
  # разобрать page.json; выйти, когда records пуст
  offset=$((offset + 500))
done
<?php
$offset = 0;
$all    = [];

do {
    $url = 'https://ваш-сайт.ru/api/v1/lists/4/records/?'
         . http_build_query(['limit' => 500, 'offset' => $offset]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer КЛЮЧ'],
    ]);
    $page = json_decode(curl_exec($ch), true);
    curl_close($ch);

    $rows = $page['records'] ?? [];
    $all  = array_merge($all, $rows);
    $offset += 500;
} while ($rows);          /* пустая страница — записи кончились */

echo 'получено: ', count($all), PHP_EOL;
import requests

session = requests.Session()
session.headers['Authorization'] = 'Bearer КЛЮЧ'

offset, all_rows = 0, []
while True:
    page = session.get(
        'https://ваш-сайт.ru/api/v1/lists/4/records/',
        params={'limit': 500, 'offset': offset},
        timeout=30,
    ).json()

    rows = page.get('records', [])
    if not rows:
        break
    all_rows += rows
    offset += 500

print('получено:', len(all_rows))
const headers = { Authorization: 'Bearer КЛЮЧ' };
let offset = 0;
const all = [];

for (;;) {
  const url = new URL('https://ваш-сайт.ru/api/v1/lists/4/records/');
  url.searchParams.set('limit', '500');
  url.searchParams.set('offset', String(offset));

  const page = await (await fetch(url, { headers })).json();
  if (!page.records?.length) break;

  all.push(...page.records);
  offset += 500;
}

console.log('получено:', all.length);

Больше 500 записей за раз не отдаётся: ответ на десятки тысяч строк одинаково плох и для сайта, и для того, кто его разбирает.