Списки событий
Два списка событий с разным охватом и один эндпоинт для карточки конкретного события. Все три требуют токен — см. Авторизация. Токен один и тот же для всех эндпоинтов, в том числе для календаря платформы, хотя его данные не привязаны к вашему аккаунту.
Какие события попадают в выдачу
Только опубликованные и не скрытые события — та же логика, что и у каталога на сайте: событие должно быть активно (опубликовано организатором) и не иметь отметки «скрыто». Черновики и скрытые события не появляются ни в одном из списков и не отдаются по прямому id — в том числе если это ваш собственный черновик.
Календарь платформы
GET /api/1.0/calendar
Все опубликованные события всей платформы, всех организаторов — не только ваши. Без параметра from возвращает события с end_date не раньше сегодняшнего дня: прошедшие события по умолчанию не показываются.
Пример запроса
curl -s "https://myrace.info/api/1.0/calendar?sport=trail,running&country=RU&limit=20" \
-H "Authorization: Bearer <ВАШ_ТОКЕН>"
События вашего аккаунта
GET /api/1.0/events
Только события, принадлежащие аккаунту, которому выдан токен, — scope неявный, по токену. Параметра, чтобы указать «чужой» аккаунт, нет.
В отличие от календаря платформы, здесь нет дефолта по дате: если from не задан, в выдаче есть и уже прошедшие события вашего аккаунта.
Пример запроса
curl -s "https://myrace.info/api/1.0/events?sport=trail,running&from=2026-01-01&limit=20" \
-H "Authorization: Bearer <ВАШ_ТОКЕН>"
Пример ответа (сокращённо, формат общий для обоих списков)
{
"events": [
{
"id": "1994",
"name": "Горный трейл 2026",
"sports": [
{ "code": "trail", "name": "Трейл" }
],
"start_date": "2026-05-16",
"end_date": "2026-05-17",
"location": {
"id": "42",
"country": "RU",
"city": "Сочи",
"latitude": 43.6028,
"longitude": 39.7342
},
"url": "https://myrace.info/events/48213",
"activities": [
{
"id": "5021",
"name": "42 км",
"sport": { "code": "trail", "name": "Трейл" },
"start_date": "2026-05-16",
"end_date": "2026-05-16"
}
],
"updated_at": "2026-04-01T10:15:30.000Z"
}
],
"next_page_token": "MjAyNi0wNS0xNnw0ODIxMw=="
}
Параметры
Оба списка принимают одинаковый набор параметров.
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
sport | строка | нет | Коды видов спорта через запятую, см. Виды спорта. Событие попадает в выдачу, если совпадает хотя бы один код (логика ИЛИ). Пример: sport=trail,running |
country | строка | нет | Код страны локации события, ISO 3166-1 alpha-2, без учёта регистра. Пример: country=RU |
from | строка, дата YYYY-MM-DD | нет | Нижняя граница диапазона. У календаря платформы по умолчанию — сегодняшняя дата; у событий вашего аккаунта дефолта нет (см. выше) |
to | строка, дата YYYY-MM-DD | нет | Верхняя граница диапазона, включительно. Возвращаются события, которые начинаются не позже этой даты — событие, стартовавшее до to, но продолжающееся после, всё равно попадёт в выдачу |
updated_since | строка, дата-время ISO 8601 UTC | нет | Возвращает события, изменённые не раньше указанного момента. Подробнее — в разделе Инкрементальная синхронизация |
limit | целое число | нет | Размер страницы, от 1 до 100. По умолчанию 50 |
page_token | строка | нет | Непрозрачный токен страницы из next_page_token предыдущего ответа |
Если to указан раньше from, запрос вернёт 400.
Поведение фильтров
sport. Если среди переданных кодов есть хотя бы один, не совпадающий ни с одним активным видом спорта из каталога (см. Виды спорта), запрос вернёт 400 с перечислением неизвестных кодов вmessageи именем параметраsportвparam. Регистр и пробелы вокруг кода не важны.country. Если код не похож на двухбуквенный код страны (например, трёхбуквенный или с цифрами), запрос вернёт 400. А если код синтаксически корректен, но такой страны нет в справочнике платформы, ошибки не будет — запрос вернёт200 OKс пустым спискомevents.
Пагинация
Пагинация курсорная (keyset), не по номеру страницы. Запросите первую страницу без page_token; если в ответе есть поле next_page_token, подставьте его значение в page_token следующего запроса. На последней странице поле next_page_token в ответе отсутствует (его нет в JSON, это не null). Токен — непрозрачная строка, не пытайтесь разобрать её формат.
Инкрементальная синхронизация
Параметр updated_since отбирает события, у которых дата изменения не раньше указанной. Учитывается:
- собственное время изменения события;
- время изменения любой из его активностей.
В ответе используется большее из этих двух значений — поле updated_at в карточке события (см. таблицу полей ниже).
⚠️ Известное ограничение. Изменение адреса, города или координат локации события не обновляет
updated_atсамого события. Если вы синхронизируетесь поupdated_since, точечное изменение локации без других изменений в событии или его активностях может остаться незамеченным. Периодически делайте полную синхронизацию безupdated_since, чтобы подхватить такие изменения.
Одно событие
GET /api/1.0/events/{id}
{id} — id события (значение поля id из одного из списков).
Эндпоинт отдаёт только события вашего аккаунта. Ответ — объект события в том же формате, что внутри массива events у списков, но без обёртки: прямо на верхнем уровне ответа, без ключа events.
Если событие не найдено, не распознано как id, принадлежит другому организатору или является вашим неопубликованным черновиком — во всех случаях одинаковый 404:
{
"error": {
"code": "not_found",
"message": "Event not found: 999999"
}
}
⚠️ По ответу нельзя отличить «это не ваше событие» от «такого события не существует» — это сделано специально, чтобы не раскрывать чужие данные.
Язык ответа
Все эндпоинты понимают заголовок Accept-Language (ru, en, es или fr). Если заголовок не передан или язык не поддерживается, ответ возвращается на русском. Используемый язык приходит обратно в заголовке Content-Language.
Кэширование
Все эндпоинты отдают заголовок ETag. Передайте его значение из предыдущего ответа в заголовке If-None-Match — если данные не изменились, API ответит 304 Not Modified без тела.
Значение Cache-Control зависит от эндпоинта — ответ календаря платформы не привязан к аккаунту и кешируется дольше:
| Эндпоинт | Cache-Control |
|---|---|
/calendar, /sports | public, max-age=300 |
/events, /events/{id} | private, max-age=60 |
Поля события
| Поле | Тип | Описание |
|---|---|---|
id | строка | Существующий публичный id события, как есть, без преобразований |
name | строка | Название события |
sports | массив Sport | Виды спорта события. Собираются из видов спорта активностей события (без повторов); если ни у одной активности вид спорта не указан, берётся вид спорта самого события. Если и он не указан — пустой массив |
start_date | строка, дата | Дата начала события |
end_date | строка, дата | Дата окончания события. Если дата окончания не задана, равна дате начала |
location | объект Location или null | Локация события. null, если локация не указана |
url | строка, URL | Ссылка на страницу события на сайте MyRace |
activities | массив Activity | Активности события. Не у каждого события есть активности — массив может быть пустым |
updated_at | строка, дата-время ISO 8601 UTC | Время последнего изменения — см. Инкрементальная синхронизация |
Поля активности (Activity)
| Поле | Тип | Описание |
|---|---|---|
id | строка | Существующий публичный id активности, как есть, без преобразований |
name | строка | Название активности |
sport | объект Sport или null | Вид спорта активности, если указан |
start_date | строка, дата | Дата начала активности. Если не задана отдельно, равна дате начала события |
end_date | строка, дата | Дата окончания активности. Если не задана, равна дате начала активности |
Поля локации (Location)
| Поле | Тип | Описание |
|---|---|---|
id | строка | Внутренний id локации — у локации нет отдельного публичного id, поэтому отдаётся он |
country | строка или null | Код страны, ISO 3166-1 alpha-2 |
city | строка или null | Название города |
latitude | число или null | Широта |
longitude | число или null | Долгота |