Перейти к содержимому

Разработчики

Справочник 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 /appsapps:readСписок приложений
POST /appsapps:writeСоздать приложение
GET /apps/{id}apps:readПолучить приложение
PATCH /apps/{id}apps:writeОбновить приложение
DELETE /apps/{id}apps:writeУдалить приложение
PUT /apps/{id}/linksapps:writeЗадать или удалить ссылки на магазины
POST /apps/{id}/metadataapps:writeИмпортировать данные из карточки в магазине
GET /apps/{id}/analyticsanalytics:readИтоги, ряд по дням и разбивки
GET /apps/{id}/qrapps:readИзображение QR-кода
GET /webhookswebhooks:manageСписок подписок на вебхуки
POST /webhookswebhooks:manageСоздать подписку на вебхук
DELETE /webhooks/{id}webhooks:manageУдалить подписку на вебхук

Объект приложения

ПолеТипОписание
idstringULID приложения
namestringНазвание приложения
slugstringПуть умной ссылки: mapps.one/{slug}
statusstringlive, paused или suspended
tagline, descriptionstring или nullТекст страницы
categorystring или nullКлюч категории, например health-fitness или productivity
page_themestringclean, midnight или vivid
accent_colorstring или nullЦвет в формате hex, например #16a34a
developerobjectname, website и email
social_linksobjectЗаполненные профили в соцсетях с ключами по названию сети: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit
featuresarrayФункции с полями icon, title и description
listed_in_explorebooleanПоказывается ли приложение в Каталоге
utm_passthroughbooleanПередаются ли UTM-метки в магазины
redirect_rulesobjectНазначение для каждой платформы, с подставленными значениями по умолчанию
icon_urlstring или nullПубличный URL иконки
ratingobject или nullvalue и count из магазина
urlsobjectПубличные URL: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. Юридические URL возвращают 404, пока документ не опубликован.
linksobjectСсылки на магазины с ключами по магазину, у каждой есть url, status (unverified, verified или invalid) и verified_at. Включаются в ответы для одного приложения.
screenshotsarrayСкриншоты с полями url, width и height. Включаются после импорта метаданных.
created_at, updated_atstringМетки времени в формате 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, пока не завершится фоновая проверка. Чтобы заполнить иконку, скриншоты и описание, затем вызовите Импорт метаданных из магазина.

Обновление приложения

Передавайте только те поля, которые хотите изменить.

ПолеТип
namestring
slugstring. Изменение сразу ломает старую ссылку.
tagline, descriptionstring или null
categoryключ категории или null
page_themeclean, midnight или vivid
accent_color#rrggbb или null
utm_passthrough, listed_in_exploreboolean
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 принимает следующие параметры запроса:

ПараметрОписание
range7d, 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. Мы можем в любой момент добавлять эндпоинты, поля и типы событий, поэтому игнорируйте поля, которые вам незнакомы. Изменения, нарушающие совместимость, будут выпускаться в новой версии с заблаговременным уведомлением.