OVD-Info · Legacy V1 API repression.net

Read-only доступ к данным о политических преследованиях в России — контракт старого сервиса, на новых данных

← Public API

Обзор

Тот же контракт (роуты, форма ответа, названия полей), что был у старого сервиса, ранее отдававшегося с repression.net/en/api — для существующих интеграций, которые уже написаны под него. Это старый API: новые возможности (карточка персоны с адресом для писем и «Весточкой», уголовные дела, реестры, оценки правозащитников, хронология событий одним ответом) в него не добавляются — они выходят только в Public API (датасет profiles). Для новых интеграций используйте его.

Базовый путь: http://api.repressions.org/v1

Аутентификация

Как и у Public API — заголовок X-API-Key на каждый запрос. У старого сервиса ключа не было вообще; это единственное намеренное отличие от исходного поведения.

Для получения ключа обратитесь к команде ОВД-Инфо по адресу data@ovdinfo.org.

Исключение — ссылки на фото (person_photo/photo): это готовые публичные URL вида /v1/persons/{id}/photo/{photo_id}, рассчитанные на прямую вставку в <img src> на сторонних страницах, поэтому ключа не требуют.

Две формы данных

Плоская (flat) — одна строка на преследование, все связанные данные (статьи, приговор, меры пресечения) уже развёрнуты в поля текущей строки. Отдаётся через GET /v1/data.

Объектная (objective) — граф из 11 связанных сущностей с references между ними, так же, как в исходном сервисе. Отдаётся через GET /v1/{коллекция} и связанные роуты ниже.

Сущности

СущностьКоллекция (URL)Описание
persecutionpersecutionsПреследование — центральная сущность, то же, что строка в плоской форме
personpersonsПреследуемый
casecasesУголовное дело
articlearticlesСтатья УК
evaluationevaluationsОценка правозащитной организации
sentencesentencesЗаседание с приговором
restraintrestraintsМера пресечения
imprisonmentimprisonmentsОтбывание наказания
locationlocationsСИЗО/колония/спецприёмник/ИВС/больница/суд (единая сущность)
citycitiesГород
pressurepressuresВнесудебное давление. Единственная сущность, не скоупленная по публикации преследования — событие давления само по себе не содержит идентифицирующих человека данных и остаётся в выдаче для региональной статистики, но pressure_persecutions обнуляется, если преследование непубличное
eventevents○ нет данных — сущность "Акции" пока не перенесена, роуты отдают 501

Эндпоинты

МетодПутьОписание
GET/v1/schemaСхема полей: ?type=flat|objective, ?language=ru|en
GET/v1/statsДата последней компиляции + число строк по каждой сущности
GET/v1/dataПлоский список преследований. С ?csv=true — выгрузка CSV-файлом
GET/v1/data/distinctУникальные значения указанных полей: ?fields=["gender_ru"]
GET/v1/{коллекция}Список записей сущности (объектная форма), с attributes и references
GET/v1/{коллекция}/distinctУникальные значения полей для этой сущности
GET/v1/{коллекция}/{id}Одна запись сущности по UUID
GET/v1/{коллекция}/{id}/referencesВсе связанные записи (по всем типам ссылок разом)
GET/v1/{коллекция}/{id}/references/{целеваяКоллекция}Связанные записи только одного типа
GET/v1/persons/{id}/photo/{photoId}Фото — публичный URL, без ключа (см. выше)

Query-параметры

ПараметрГдеОписание
languageвездеru (по умолчанию) или en
subsetвездеbasic (по умолчанию) / detailed / full / hidden — см. предупреждение ниже
fieldsвездеЯвный список полей вместо subset: ?fields=["name_ru","birth_year"]
filterdata, {коллекция}JSON-объект точных фильтров: ?filter={"gender_ru":"Женский"}. Для поля-массива в базе — совпадение по любому из значений
presetdataОдин из готовых фильтров — см. ниже. Пока считается только для плоской формы
sortBy / orderdata, {коллекция}Поле для сортировки и направление (asc/desc)
limit / skipвездеПо умолчанию 100 записей, максимум 1000 (у старого API ограничения не было)
shuffledataСлучайный порядок (работает, только если sortBy не задан)
includeStatsOnlydataВключить записи, помеченные "только для статистики" (по умолчанию скрыты)
csvdatatrue — вернуть CSV вместо JSON
references{коллекция}title (по умолчанию) — связанные записи в виде строки-заголовка; ru/en — полными атрибутами
flatten{коллекция}true — вернуть поля без обёртки attributes

Важно про subset: это не накопительный уровень, а точная принадлежность — поле показывается, только если запрошенный subset буквально есть в его собственном списке subset'ов. Поле, помеченное только как full, не появится при ?subset=detailed, хотя интуитивно могло бы. Полный список subset'ов каждого поля — в GET /v1/schema.

Presets (?preset=, только /v1/data)

ЗначениеОписание
actualПреследование активно (нет даты окончания)
imprisonedСейчас под стражей
letters / letters-nowМожно писать письма (через «Весточку»)
after-invasion / before-invasionПреследование началось после/до 24.02.2022
antiwarДело относится к антивоенным (по группе дела)

Примеры

# Схема плоской формы на английском
curl "http://api.repressions.org/v1/schema?type=flat&language=en" \
  -H "X-API-Key: <ваш_ключ>"

# Плоский список: активные преследования женщин, отсортированные по дате начала
curl "http://api.repressions.org/v1/data?preset=actual&filter={\"gender_ru\":\"Женский\"}&sortBy=persecution_started&order=desc" \
  -H "X-API-Key: <ваш_ключ>"

# То же самое — сразу файлом CSV
curl "http://api.repressions.org/v1/data?preset=actual&csv=true" \
  -H "X-API-Key: <ваш_ключ>" -o persecutions.csv

# Персона с разворотом всех связей (дело, статьи, меры пресечения…)
curl "http://api.repressions.org/v1/persons/<uuid>?subset=full" \
  -H "X-API-Key: <ваш_ключ>"

# Только связанные уголовные дела этой персоны, с полными атрибутами
curl "http://api.repressions.org/v1/persons/<uuid>/references/cases?subset=full&references=ru" \
  -H "X-API-Key: <ваш_ключ>"

# Фото — обычная публичная ссылка, ключ не нужен
<img src="http://api.repressions.org/v1/persons/<uuid>/photo/<photoId>">

Отличия от исходного API

Большинство полей воспроизведены как есть, часть — доисследована и досчитана заново (переводы на английский, слаг персоны, ссылка для переписки, тематические группы дел, изоляция в колонии, суть приговора и адрес учреждения на английском и т.п. — последние два были реальным текстом в старой базе, который просто не попал в Postgres при миграции, и теперь догружены отдельным скриптом). Известные пробелы:

ЧтоСтатус
aid (только у persecution//v1/data)Раньше — Airtable record id, инжектился в каждую запись рантаймом pp-api, а не полем схемы. Теперь — просто копия persecution_id (UUID), не исходное значение, но стабильный ключ для старых интеграций
Сущность event ("Акции")Пока не перенесена — роуты отдают 501
location_short_name_ru/enНет источника, всегда пусто
location_regime_ru/enРежим содержания (общий/строгий/особый) не был перенесён в Postgres — пусто. Не путать с типом учреждения (location_type_ru/en), который есть
Часть _en-полейПусто там, где нет отдельной колонки с переводом (не формула — реальный независимый текст)