Разработчики
Справочник API
REST API mapps.one позволяет из вашего кода, CI-конвейера или интеграции создавать и обновлять приложения, управлять ссылками на магазины, импортировать метаданные из магазинов, читать аналитику, создавать QR-коды и подписываться на вебхуки. API доступен на плане Studio.
Базовый URL
https://mapps.one/api/v1
Все запросы выполняются по HTTPS. Отправляйте тела запросов в формате JSON с заголовком Content-Type: application/json и всегда передавайте Accept: application/json, чтобы ошибки тоже возвращались в формате JSON.
Аутентификация
Создайте токен в панели управления в разделе Разработчики. Это могут делать владельцы и администраторы рабочего пространства. Дайте токену название, например «GitHub Actions», и выберите его разрешения. Токен показывается только один раз, поэтому сразу сохраните его в менеджере секретов.
Токены принадлежат рабочему пространству, а не конкретному человеку, поэтому они продолжают работать, когда кто-то уходит из команды. Срок их действия не истекает. Отзовите токен на той же странице, когда он станет не нужен или если он мог утечь.
Передавайте токен как bearer-токен:
curl https://mapps.one/api/v1/workspace \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json"
Разрешения
| Разрешение | Что позволяет |
|---|---|
apps:read | Получать список приложений и их данные, скачивать QR-коды |
apps:write | Создавать, обновлять и удалять приложения, заменять ссылки на магазины, импортировать метаданные из магазинов |
analytics:read | Читать аналитику приложений |
webhooks:manage | Получать список подписок на вебхуки, создавать и удалять их |
GET /workspace и GET /events работают с любым действительным токеном. Давайте каждой интеграции только те разрешения, которые ей нужны.
Соглашения
- ID — это ULID из 26 символов в нижнем регистре, например
01j8b2k6r3xq9v7m4n5p0s1t2w. Приложения адресуются поid, а не по слагу, поэтому смена слага никогда не ломает вашу интеграцию. - Метки времени указываются в формате ISO 8601 в UTC, например
2026-09-14T08:12:44+00:00. - Ответы оборачивают результат в ключ
data. - Ключи магазинов:
app_store,google_play,app_gallery,microsoft_storeиweb. - Ключи платформ:
ios,android,huawei,windows,macosиother. Ключи назначений — это ключи магазинов плюсlanding.
Лимиты запросов
Каждое рабочее пространство может выполнять 120 запросов в минуту, и этот лимит общий для всех его токенов. Каждый ответ содержит заголовки X-RateLimit-Limit и X-RateLimit-Remaining. При превышении лимита API отвечает 429 Too Many Requests с заголовком Retry-After, в котором указано, сколько секунд нужно подождать.
Ошибки
При ошибке возвращается тело JSON с понятным человеку сообщением message. Некоторые ошибки также содержат машиночитаемый code, а ошибки валидации перечисляют проблемы по каждому полю в errors.
| Статус | Когда |
|---|---|
401 | Токен отсутствует, недействителен или отозван. {"message": "Unauthenticated."} |
402 | План рабочего пространства не включает доступ к API. Код plan_required. |
403 | У токена нет разрешения, необходимого для этого эндпоинта. {"message": "Invalid ability provided."} |
404 | Приложение или подписка не существует либо принадлежит другому рабочему пространству. |
422 | Валидация не пройдена, или запрос не удалось выполнить. Например, код metadata_unavailable. |
429 | Превышен лимит запросов. Подождите столько секунд, сколько указано в Retry-After. |
5xx | Что-то пошло не так на нашей стороне. Повторите запрос с экспоненциальной задержкой. |
HTTP/2 402
{
"message": "API access requires the Studio plan.",
"code": "plan_required"
}
HTTP/2 422
{
"message": "This link is already taken.",
"errors": {
"slug": ["This link is already taken."]
}
}
Эндпоинты
| Метод и путь | Разрешение | Описание |
|---|---|---|
GET /workspace | любое | Рабочее пространство, план, использование и текущий токен |
GET /events | любое | Типы событий вебхуков |
GET /apps | apps:read | Список приложений |
POST /apps | apps:write | Создать приложение |
GET /apps/{id} | apps:read | Получить приложение |
PATCH /apps/{id} | apps:write | Обновить приложение |
DELETE /apps/{id} | apps:write | Удалить приложение |
PUT /apps/{id}/links | apps:write | Задать или удалить ссылки на магазины |
POST /apps/{id}/metadata | apps:write | Импортировать данные из карточки в магазине |
GET /apps/{id}/analytics | analytics:read | Итоги, ряд по дням и разбивки |
GET /apps/{id}/qr | apps:read | Изображение QR-кода |
GET /webhooks | webhooks:manage | Список подписок на вебхуки |
POST /webhooks | webhooks:manage | Создать подписку на вебхук |
DELETE /webhooks/{id} | webhooks:manage | Удалить подписку на вебхук |
Объект приложения
| Поле | Тип | Описание |
|---|---|---|
id | string | ULID приложения |
name | string | Название приложения |
slug | string | Путь умной ссылки: mapps.one/{slug} |
status | string | live, paused или suspended |
tagline, description | string или null | Текст страницы |
category | string или null | Ключ категории, например health-fitness или productivity |
page_theme | string | clean, midnight или vivid |
accent_color | string или null | Цвет в формате hex, например #16a34a |
developer | object | name, website и email |
social_links | object | Заполненные профили в соцсетях с ключами по названию сети: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit |
features | array | Функции с полями icon, title и description |
listed_in_explore | boolean | Показывается ли приложение в Каталоге |
utm_passthrough | boolean | Передаются ли UTM-метки в магазины |
redirect_rules | object | Назначение для каждой платформы, с подставленными значениями по умолчанию |
icon_url | string или null | Публичный URL иконки |
rating | object или null | value и count из магазина |
urls | object | Публичные URL: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. Юридические URL возвращают 404, пока документ не опубликован. |
links | object | Ссылки на магазины с ключами по магазину, у каждой есть url, status (unverified, verified или invalid) и verified_at. Включаются в ответы для одного приложения. |
screenshots | array | Скриншоты с полями url, width и height. Включаются после импорта метаданных. |
created_at, updated_at | string | Метки времени в формате ISO 8601 |
Получение приложения
curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json"
{
"data": {
"id": "01j8b2k6r3xq9v7m4n5p0s1t2w",
"name": "Habitly",
"slug": "habitly",
"status": "live",
"tagline": "Build habits that stick",
"description": "Habitly helps you build small daily habits with gentle reminders and streaks.",
"category": "health-fitness",
"page_theme": "clean",
"accent_color": "#16a34a",
"developer": {
"name": "Habitly Labs",
"website": "https://habitly.app",
"email": "hello@habitly.app"
},
"social_links": {
"instagram": "https://instagram.com/habitly.app"
},
"features": [
{ "icon": "bell", "title": "Gentle reminders", "description": "Nudges at the time you choose." }
],
"listed_in_explore": true,
"utm_passthrough": true,
"redirect_rules": {
"ios": "app_store",
"android": "google_play",
"huawei": "app_gallery",
"windows": "microsoft_store",
"macos": "landing",
"other": "landing"
},
"icon_url": "https://mapps.one/storage/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/icon/icon.png",
"rating": { "value": 4.8, "count": 12450 },
"urls": {
"smart_link": "https://mapps.one/habitly",
"landing_page": "https://mapps.one/habitly/page",
"qr_svg": "https://mapps.one/habitly/qr.svg",
"qr_png": "https://mapps.one/habitly/qr.png",
"privacy_policy": "https://mapps.one/habitly/privacy",
"terms": "https://mapps.one/habitly/terms"
},
"links": {
"app_store": {
"url": "https://apps.apple.com/app/id1612345678",
"status": "verified",
"verified_at": "2026-09-14T08:12:44+00:00"
},
"google_play": {
"url": "https://play.google.com/store/apps/details?id=com.habitly.app",
"status": "verified",
"verified_at": "2026-09-14T08:12:46+00:00"
}
},
"created_at": "2026-09-01T11:20:03+00:00",
"updated_at": "2026-09-14T08:12:46+00:00"
}
}
Список приложений
Возвращает приложения рабочего пространства. Результаты разбиты на страницы: переходите по links.next или передавайте ?page=2 и так далее, пока значение не станет null.
curl "https://mapps.one/api/v1/apps?page=1" \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json"
{
"data": [
{ "id": "01j8b2k6r3xq9v7m4n5p0s1t2w", "name": "Habitly", "slug": "habitly", "status": "live" },
{ "id": "01j8d5r2w9y6a3c0e7g4j1m8p5", "name": "Habitly Focus", "slug": "habitly-focus", "status": "paused" }
],
"links": {
"first": "https://mapps.one/api/v1/apps?page=1",
"last": "https://mapps.one/api/v1/apps?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 25,
"total": 2
}
}
В этом примере объекты приложений сокращены. Каждый элемент содержит полный набор полей.
Создание приложения
| Поле | Обязательное | Описание |
|---|---|---|
name | Да | Название приложения, до 120 символов |
slug | Нет | От 3 до 40 строчных букв, цифр и одиночных дефисов. Если поле не указано, свободный слаг генерируется из названия. |
links | Нет | Ссылки на магазины с ключами по магазину, в том же формате, что и в разделе Задание ссылок на магазины |
Также можно передать любые поля, перечисленные в разделе Обновление приложения.
curl https://mapps.one/api/v1/apps \
-X POST \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"name": "Habitly",
"slug": "habitly",
"links": {
"app_store": "https://apps.apple.com/us/app/habitly/id1612345678",
"google_play": "https://play.google.com/store/apps/details?id=com.habitly.app"
}
}'
Ответ — 201 Created с объектом нового приложения. Ссылки на магазины сохраняются в канонической форме со статусом unverified, пока не завершится фоновая проверка. Чтобы заполнить иконку, скриншоты и описание, затем вызовите Импорт метаданных из магазина.
Обновление приложения
Передавайте только те поля, которые хотите изменить.
| Поле | Тип |
|---|---|
name | string |
slug | string. Изменение сразу ломает старую ссылку. |
tagline, description | string или null |
category | ключ категории или null |
page_theme | clean, midnight или vivid |
accent_color | #rrggbb или null |
utm_passthrough, listed_in_explore | boolean |
redirect_rules | объект, сопоставляющий ключ платформы с ключом назначения |
curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w \
-X PATCH \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"tagline": "Tiny habits, big changes",
"redirect_rules": { "macos": "landing" }
}'
Ответ — обновлённый объект приложения.
Удаление приложения
curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w \
-X DELETE \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json"
Ответ — 204 No Content. Удаление необратимо: умная ссылка, лендинг, юридические документы, медиафайлы и аналитика приложения удаляются.
Задание ссылок на магазины
PUT /apps/{id}/links принимает объект links с ключами по магазину:
- URL добавляет или заменяет ссылку для этого магазина,
nullили пустая строка удаляет её,- магазины, которые вы не указали, не меняются.
Каждый URL должен быть корректной ссылкой на карточку в своём магазине: ссылкой apps.apple.com с ID приложения, ссылкой play.google.com с ID пакета и так далее. Ссылка web может быть любым адресом http или https. Длина URL — до 1024 символов. Ссылки сохраняются в канонической форме и проверяются в фоновом режиме.
curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/links \
-X PUT \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"links": {
"app_gallery": "https://appgallery.huawei.com/app/C109876543",
"web": null
}
}'
Ответ — объект приложения, включая links. Недопустимая ссылка возвращает 422:
{
"message": "This is not a valid Google Play link.",
"errors": {
"links.google_play": ["This is not a valid Google Play link."]
}
}
Импорт метаданных из магазина
POST /apps/{id}/metadata считывает карточку в App Store (или карточку в Google Play, если читаемой ссылки на App Store нет) и импортирует её данные.
| Поле | Описание |
|---|---|
overwrite | Необязательное, по умолчанию false. Если false, заполняются только пустые поля, а скриншоты добавляются, только если у приложения их нет. Если true, заменяются название, иконка, текст и скриншоты. Рейтинг и цена обновляются всегда. |
curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/metadata \
-X POST \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{ "overwrite": true }'
Ответ — объект приложения, включая links и screenshots; кроме того, отправляется вебхук app.metadata_fetched. Если не удаётся прочитать ни одну карточку:
HTTP/2 422
{
"message": "The store listing could not be read. Add a valid App Store or Google Play link first.",
"code": "metadata_unavailable"
}
Аналитика
GET /apps/{id}/analytics принимает следующие параметры запроса:
| Параметр | Описание |
|---|---|
range | 7d, 30d, 90d, 12m или custom. По умолчанию 30d. |
from, to | Даты в формате YYYY-MM-DD, обе включительно, для range=custom. to не может быть позже сегодняшнего дня. |
timezone | Часовой пояс IANA, например Europe/Istanbul, по которому определяются границы дней. По умолчанию UTC. |
curl "https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/analytics?range=7d&timezone=Europe/Istanbul" \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json"
{
"data": {
"app": { "id": "01j8b2k6r3xq9v7m4n5p0s1t2w", "slug": "habitly" },
"range": {
"key": "7d",
"from": "2026-09-07T21:00:00+00:00",
"to": "2026-09-14T21:00:00+00:00",
"timezone": "Europe/Istanbul",
"clamped_to_plan": false
},
"summary": {
"clicks": 1284,
"visitors": 902,
"page_views": 356,
"store_clicks": 141
},
"daily": {
"2026-09-08": 152,
"2026-09-09": 171,
"2026-09-10": 168,
"2026-09-11": 205,
"2026-09-12": 214,
"2026-09-13": 190,
"2026-09-14": 184
},
"breakdowns": {
"os": { "iOS": 702, "Android": 431, "Windows": 88, "macOS": 63 },
"country": { "TR": 512, "US": 298, "": 236, "DE": 141, "GB": 97 },
"source": { "instagram": 488, "direct": 402, "qr": 190, "google": 121, "x": 83 },
"destination": { "app_store": 640, "google_play": 399, "landing": 214, "deep_link": 31 },
"utm_campaign": { "": 796, "launch": 402, "newsletter-sep": 86 }
}
}
}
fromвключается в диапазон, аto— нет. Оба значения — моменты времени в UTC.clamped_to_planравноtrue, если запрошенный диапазон был сокращён до истории, доступной на плане.dailyсчитает клики по локальным датам, включая дни без кликов.- Разбивки содержат до 10 значений, начиная с самых частых. Пустой ключ
""означает, что значение неизвестно или не задано. - Определения метрик приведены на странице Аналитика.
QR-код
GET /apps/{id}/qr возвращает изображение. Используйте format=svg (по умолчанию) или format=png, а также те же параметры, что и у публичных URL QR-кодов: fg, bg, margin, ecc, size, logo и download. Подробнее: QR-коды и пресс-кит.
curl "https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/qr?format=png&size=2048&ecc=Q" \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-o habitly-qr.png
Рабочее пространство
GET /workspace возвращает рабочее пространство, лимиты и функции его плана, текущее использование и токен, с которым выполнен запрос. Это удобный первый вызов, чтобы проверить, что токен работает.
{
"data": {
"id": "01j8a0f4c7d2e9h6k3m5n8q1r4",
"name": "Habitly Labs",
"plan": {
"key": "studio",
"name": "Studio",
"limits": {
"apps": null,
"analytics_days": 730,
"members": 10,
"custom_domains": 25,
"legal_locales": null,
"screenshots": 10,
"webhooks": 10
},
"features": ["remove_badge", "all_themes", "accent_color", "qr_logo", "legal_full", "deep_links", "press_kit", "analytics_export", "custom_domains", "team", "folders", "ab_testing", "api", "webhooks", "white_label"]
},
"usage": { "apps": 12, "custom_domains": 3, "members": 4 },
"token": { "name": "GitHub Actions", "abilities": ["apps:read", "apps:write"] }
}
}
Лимит null означает отсутствие ограничений.
Типы событий
GET /events возвращает список типов событий вебхуков с кратким описанием. Интеграции могут использовать его, чтобы построить выбор событий.
{
"data": [
{ "type": "app.created", "description": "An app was added to the workspace." },
{ "type": "app.updated", "description": "App details, links or page settings changed." },
{ "type": "app.deleted", "description": "An app was deleted." },
{ "type": "app.status_changed", "description": "An app went live, was paused or was suspended." },
{ "type": "app.metadata_fetched", "description": "Store metadata was imported for an app." },
{ "type": "legal.published", "description": "A privacy policy or terms document was published." },
{ "type": "domain.verified", "description": "A custom domain was verified." },
{ "type": "link.clicked", "description": "Every smart link click. High volume." },
{ "type": "analytics.daily_summary", "description": "Yesterday's click totals for each app, sent once a day." }
]
}
Подписки на вебхуки
Создавайте подписки на вебхуки из кода, например когда пользователь подключает вашу интеграцию, и удаляйте их, когда он отключается. POST /webhooks принимает:
| Поле | Обязательное | Описание |
|---|---|---|
url | Да | Публичный URL с https, который получает события |
events | Да | Массив типов событий или ["*"] для всех событий |
description | Нет | До 160 символов, показывается в панели управления |
curl https://mapps.one/api/v1/webhooks \
-X POST \
-H "Authorization: Bearer $MAPPS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.zapier.com/hooks/catch/1234567/abcde12/",
"events": ["link.clicked"],
"description": "Zapier: clicks to Google Sheets"
}'
HTTP/2 201
{
"data": {
"id": "01j8c1p4s7v0y3b6e9h2k5n8q1",
"url": "https://hooks.zapier.com/hooks/catch/1234567/abcde12/",
"events": ["link.clicked"],
"description": "Zapier: clicks to Google Sheets",
"is_active": true,
"secret": "9f2c4e7a1b8d3f6e0a5c2b9d7e4f1a3c6b8d0e2f4a6c8e0b2d4f6a8c0e2b4d61",
"created_at": "2026-09-14T10:05:12+00:00"
}
}
Секрет подписи secret возвращается только при создании подписки. Используйте его, чтобы проверять подписи. В рабочем пространстве Studio может быть до 10 эндпоинтов вебхуков. Удалить подписку можно запросом DELETE /webhooks/{id}, который возвращает 204 No Content.
Пример: публикация бета-версии из CI
Этот скрипт создаёт приложение, добавляет ссылку на Google Play, импортирует карточку и выводит умную ссылку. Для него нужны curl, jq и токен с разрешением apps:write.
#!/usr/bin/env bash
set -euo pipefail
API="https://mapps.one/api/v1"
HEADERS=(-H "Authorization: Bearer $MAPPS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json")
APP_ID=$(curl -sf "${HEADERS[@]}" -X POST "$API/apps" \
-d '{"name": "Habitly Beta", "slug": "habitly-beta"}' | jq -r '.data.id')
curl -sf "${HEADERS[@]}" -X PUT "$API/apps/$APP_ID/links" \
-d '{"links": {"google_play": "https://play.google.com/store/apps/details?id=com.habitly.beta"}}' > /dev/null
curl -sf "${HEADERS[@]}" -X POST "$API/apps/$APP_ID/metadata" \
-d '{"overwrite": true}' | jq -r '.data.urls.smart_link'
Версионирование
Это версия 1 API. Мы можем в любой момент добавлять эндпоинты, поля и типы событий, поэтому игнорируйте поля, которые вам незнакомы. Изменения, нарушающие совместимость, будут выпускаться в новой версии с заблаговременным уведомлением.