Базовая архитектура и структура данных
API исторического архива Reddit представляет сохраненные публикации и комментарии независимо от официального сервиса. Для интеграции на Python или JavaScript достаточно HTTP-клиента, который отправляет запросы и разбирает JSON-ответы. Данные не обновляются как живая лента. В приложении отделяйте полученные архивные сведения от текущего состояния исходных страниц Reddit, а сетевой ответ — от результата последующего анализа записей.
При работе с данными важно понимать их структуру. Сервер всегда возвращает плоские записи, а не объединенные древовидные структуры веток. Это означает, что поля parent_id или link_id могут присутствовать, но они не гарантируют наличия полной иерархии. Клиенту необходимо самостоятельно группировать элементы, если требуется отобразить структуру дискуссии в приложении.
Параметр id обязателен при обращении к /v1/item за конкретной записью. Это требование к входному запросу, а не утверждение об отсутствии идентификаторов в ответах других маршрутов. Для /v1/posts и /v1/comments фильтр id не предусмотрен. Если связь с родительской записью отсутствует в полученной выборке, не достраивайте ее по предположению: сохраните доступные поля и обозначьте неполный контекст.
Фильтрация запросов и ограничения данных
Для поиска используйте q, subreddit и author; тип записи задается через kind со значением post или comment. Параметры from и to принимают даты YYYY-MM-DD в UTC, причем день to включается в диапазон. min_score отфильтровывает записи по числовому рейтингу, но не сортирует их. Порядок _doc не является хронологическим, релевантным или упорядоченным по оценке. Для списка сообществ предусмотрен необязательный prefix.
За один запрос можно получить не более 100 записей; limit задается от 1 до 100. Параметр page выбирает одну страницу с номером от 1 до 100, поэтому обход нескольких страниц требует отдельных запросов. Общее число совпадений может быть точным, нижней границей или неизвестным. Нижняя граница не равна точному итогу, а обход всех разрешенных страниц не доказывает полноту выборки.
Параметр kind принимает только значения post или comment. Поля parent_id и link_id не являются доступными фильтрами запроса. Если эти поля присутствуют в ответах, приложение может использовать их для локальной группировки уже полученных записей. Это не дает возможности запросить через API полную ветку по родительскому идентификатору и не гарантирует получение всех связанных сообщений.
Протокол обмена и обработка ошибок
Каждый успешный запрос на получение данных расходует один кредит, включая запрос с пустым результатом. Цена составляет $1 за 1000 таких запросов. Некорректные запросы не списывают кредиты, а сбой вышестоящего сервиса возвращает зарезервированный кредит. Публичный /v1/status не тарифицируется: он подтверждает ответ HTTP-сервера и сообщает статическое описание сервиса, но не проверяет поиск или наличие конкретных архивных записей.
При работе с API необходимо правильно обрабатывать стандартные коды состояния HTTP. Ошибка 401 возникает при пропуске или некорректности API-ключа. Состояние 402 информирует о недостаточном количестве кредитов на балансе. Код 429 означает превышение лимитов частоты запросов, что требует временной паузы перед повторной попыткой отправки данных. Эти коды являются неизменными для всех клиентов.
Передавайте выданный ключ в заголовке X-API-Key. Для Python настройте этот заголовок у HTTP-клиента, для JavaScript — у серверного запроса fetch; не помещайте секрет в код, доставляемый браузерам посетителей. Проверяйте код ответа до разбора полезных данных. HTTP 400 указывает на некорректный запрос. Исправление параметров, замена ключа и ожидание после ограничения частоты — разные действия, которые стоит различать в обработчике ошибок.
Маршруты API
| Метод | Маршрут | Параметры |
|---|---|---|
GET | /v1/search | q, subreddit, author, kind, from, to, min_score, limit, page |
GET | /v1/posts | q, subreddit, author, kind, from, to, min_score, limit, page |
GET | /v1/comments | q, subreddit, author, kind, from, to, min_score, limit, page |
GET | /v1/item | id |
GET | /v1/subreddits | prefix |
GET | /v1/status | — |
Параметры запроса
| Параметр | Значение / тип / диапазон |
|---|---|
q | text |
subreddit | keyword |
author | keyword |
kind | post | comment |
from | ISO date |
to | ISO date |
min_score | integer |
limit | 1–100 |
page | 1–100 |
id | item ID |
prefix | subreddit prefix |
curl -H "Authorization: Bearer YOUR_API_KEY" 'https://api.redditapistack.com/v1/search?q=research&limit=10'
import json, urllib.request
request = urllib.request.Request('https://api.redditapistack.com/v1/search?q=research&limit=10', headers={"Authorization": "Bearer YOUR_API_KEY"})
with urllib.request.urlopen(request) as response:
print(json.load(response))
fetch("https://api.redditapistack.com/v1/search?q=research&limit=10", {headers: {Authorization: "Bearer YOUR_API_KEY"}})
.then(response => response.json()).then(console.log);