Przejdź do treści

Dla programistów

Dokumentacja API

REST API mapps.one pozwala tworzyć i aktualizować aplikacje, zarządzać linkami do sklepów, importować metadane ze sklepów, odczytywać analitykę, generować kody QR i subskrybować webhooki z poziomu własnego kodu, pipeline’u CI lub integracji. API jest dostępne w planie Studio.

Bazowy adres URL

https://mapps.one/api/v1

Wszystkie żądania używają HTTPS. Treść żądań wysyłaj jako JSON z nagłówkiem Content-Type: application/json i zawsze wysyłaj Accept: application/json, aby błędy również były zwracane jako JSON.

Uwierzytelnianie

Utwórz token w panelu w sekcji Dla programistów. Mogą to zrobić właściciele i administratorzy przestrzeni roboczej. Nadaj tokenowi nazwę, np. „GitHub Actions”, i wybierz jego uprawnienia. Token jest wyświetlany tylko raz, więc od razu zapisz go w menedżerze sekretów.

Tokeny należą do przestrzeni roboczej, a nie do konkretnej osoby, więc działają nadal, gdy ktoś opuści zespół. Nie wygasają. Unieważnij token na tej samej stronie, gdy nie jest już potrzebny lub gdy mógł wyciec.

Wysyłaj token jako token typu Bearer:

curl https://mapps.one/api/v1/workspace \
  -H "Authorization: Bearer $MAPPS_TOKEN" \
  -H "Accept: application/json"

Uprawnienia

UprawnieniePozwala na
apps:readWyświetlanie listy i odczyt aplikacji, pobieranie kodów QR
apps:writeTworzenie, aktualizowanie i usuwanie aplikacji, zastępowanie linków do sklepów, import metadanych ze sklepów
analytics:readOdczyt analityki aplikacji
webhooks:manageWyświetlanie listy, tworzenie i usuwanie subskrypcji webhooków

GET /workspace i GET /events działają z każdym prawidłowym tokenem. Każdej integracji nadawaj tylko te uprawnienia, których potrzebuje.

Konwencje

  • Identyfikatory to 26-znakowe identyfikatory ULID zapisane małymi literami, np. 01j8b2k6r3xq9v7m4n5p0s1t2w. Aplikacje są wskazywane przez id, a nie przez slug, więc zmiana sluga nigdy nie psuje twojej integracji.
  • Znaczniki czasu są podawane w formacie ISO 8601 w UTC, np. 2026-09-14T08:12:44+00:00.
  • Odpowiedzi opakowują wynik w klucz data.
  • Klucze sklepów to app_store, google_play, app_gallery, microsoft_store i web.
  • Klucze platform to ios, android, huawei, windows, macos i other. Klucze miejsc docelowych to klucze sklepów oraz landing.

Limity żądań

Każda przestrzeń robocza może wysłać 120 żądań na minutę, wspólnie dla wszystkich swoich tokenów. Każda odpowiedź zawiera nagłówki X-RateLimit-Limit i X-RateLimit-Remaining. Po przekroczeniu limitu API odpowiada kodem 429 Too Many Requests z nagłówkiem Retry-After, który podaje liczbę sekund oczekiwania.

Błędy

Błędy zwracają treść JSON z czytelnym dla człowieka komunikatem message. Niektóre błędy zawierają też przeznaczony do przetwarzania maszynowego kod code, a błędy walidacji wymieniają problemy dla poszczególnych pól w errors.

StatusKiedy
401Brak tokenu albo token jest nieprawidłowy lub unieważniony. {"message": "Unauthenticated."}
402Plan przestrzeni roboczej nie obejmuje dostępu do API. Kod plan_required.
403Token nie ma uprawnienia wymaganego przez ten endpoint. {"message": "Invalid ability provided."}
404Aplikacja lub subskrypcja nie istnieje albo należy do innej przestrzeni roboczej.
422Walidacja nie powiodła się lub nie udało się zrealizować żądania. Na przykład kod metadata_unavailable.
429Przekroczono limit żądań. Odczekaj liczbę sekund podaną w Retry-After.
5xxCoś poszło nie tak po naszej stronie. Ponów żądanie z wykładniczo rosnącymi odstępami (exponential backoff).
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."]
  }
}

Endpointy

Metoda i ścieżkaUprawnienieOpis
GET /workspacedowolnePrzestrzeń robocza, plan, wykorzystanie i bieżący token
GET /eventsdowolneTypy zdarzeń webhooków
GET /appsapps:readLista aplikacji
POST /appsapps:writeTworzenie aplikacji
GET /apps/{id}apps:readPobieranie aplikacji
PATCH /apps/{id}apps:writeAktualizowanie aplikacji
DELETE /apps/{id}apps:writeUsuwanie aplikacji
PUT /apps/{id}/linksapps:writeUstawianie lub usuwanie linków do sklepów
POST /apps/{id}/metadataapps:writeImport danych z wpisu w sklepie
GET /apps/{id}/analyticsanalytics:readSumy, seria dzienna i podziały
GET /apps/{id}/qrapps:readObraz kodu QR
GET /webhookswebhooks:manageLista subskrypcji webhooków
POST /webhookswebhooks:manageTworzenie subskrypcji webhooka
DELETE /webhooks/{id}webhooks:manageUsuwanie subskrypcji webhooka

Obiekt aplikacji

PoleTypOpis
idciąg znakówULID aplikacji
nameciąg znakówNazwa aplikacji
slugciąg znakówŚcieżka inteligentnego linku: mapps.one/{slug}
statusciąg znakówlive, paused lub suspended
tagline, descriptionciąg znaków lub nullTekst strony
categoryciąg znaków lub nullKlucz kategorii, np. health-fitness lub productivity
page_themeciąg znakówclean, midnight lub vivid
accent_colorciąg znaków lub nullKolor w zapisie szesnastkowym, np. #16a34a
developerobiektname, website i email
social_linksobiektUzupełnione profile w mediach społecznościowych, z kluczami według serwisu: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit
featurestablicaElementy listy funkcji z polami icon, title i description
listed_in_explorewartość logicznaCzy aplikacja pojawia się w sekcji Odkrywaj
utm_passthroughwartość logicznaCzy tagi UTM są przekazywane do sklepów
redirect_rulesobiektMiejsce docelowe dla każdej platformy, z uzupełnionymi wartościami domyślnymi
icon_urlciąg znaków lub nullPubliczny adres URL ikony
ratingobiekt lub nullvalue i count ze sklepu
urlsobiektPubliczne adresy URL: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. Adresy URL dokumentów prawnych zwracają 404, dopóki dokument nie zostanie opublikowany.
linksobiektLinki do sklepów z kluczami według sklepu, każdy z polami url, status (unverified, verified lub invalid) i verified_at. Dołączane do odpowiedzi dotyczących pojedynczej aplikacji.
screenshotstablicaZrzuty ekranu z polami url, width i height. Dołączane po imporcie metadanych.
created_at, updated_atciąg znakówZnaczniki czasu w formacie ISO 8601

Pobieranie aplikacji

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"
  }
}

Lista aplikacji

Zwraca aplikacje z przestrzeni roboczej. Wyniki są stronicowane: podążaj za links.next lub przekazuj ?page=2, dopóki nie przyjmie wartości 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
  }
}

W tym przykładzie obiekty aplikacji są skrócone. Każdy element zawiera pełny zestaw pól.

Tworzenie aplikacji

PoleWymaganeOpis
nameTakNazwa aplikacji, do 120 znaków
slugNieOd 3 do 40 małych liter, cyfr i pojedynczych myślników. Jeśli go pominiesz, wolny slug zostanie wygenerowany z nazwy.
linksNieLinki do sklepów z kluczami według sklepu, w tym samym formacie co w sekcji Ustawianie linków do sklepów

Możesz też wysłać dowolne pola wymienione w sekcji Aktualizowanie aplikacji.

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"
    }
  }'

Odpowiedź to 201 Created z nowym obiektem aplikacji. Linki do sklepów są zapisywane w postaci kanonicznej ze statusem unverified, dopóki nie zakończy się sprawdzanie w tle. Aby uzupełnić ikonę, zrzuty ekranu i opis, wywołaj następnie Import metadanych ze sklepu.

Aktualizowanie aplikacji

Wysyłaj tylko te pola, które chcesz zmienić.

PoleTyp
nameciąg znaków
slugciąg znaków. Zmiana natychmiast psuje stary link.
tagline, descriptionciąg znaków lub null
categoryklucz kategorii lub null
page_themeclean, midnight lub vivid
accent_color#rrggbb lub null
utm_passthrough, listed_in_explorewartość logiczna
redirect_rulesobiekt mapujący klucz platformy na klucz miejsca docelowego
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" }
  }'

Odpowiedź to zaktualizowany obiekt aplikacji.

Usuwanie aplikacji

curl https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w \
  -X DELETE \
  -H "Authorization: Bearer $MAPPS_TOKEN" \
  -H "Accept: application/json"

Odpowiedź to 204 No Content. Usunięcie jest trwałe: usuwane są inteligentny link, strona docelowa, dokumenty prawne, multimedia i analityka aplikacji.

PUT /apps/{id}/links przyjmuje obiekt links z kluczami według sklepu:

  • adres URL dodaje lub zastępuje link do danego sklepu,
  • null lub pusty ciąg znaków usuwa link,
  • pominięte sklepy pozostają bez zmian.

Każdy adres URL musi prowadzić do prawidłowego wpisu w swoim sklepie: link apps.apple.com z identyfikatorem aplikacji, link play.google.com z identyfikatorem pakietu itd. Link web może być dowolnym adresem http lub https. Adresy URL mogą mieć do 1024 znaków. Linki są zapisywane w postaci kanonicznej i sprawdzane w tle.

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
    }
  }'

Odpowiedź to obiekt aplikacji zawierający links. Nieprawidłowy link zwraca 422:

{
  "message": "This is not a valid Google Play link.",
  "errors": {
    "links.google_play": ["This is not a valid Google Play link."]
  }
}

Import metadanych ze sklepu

POST /apps/{id}/metadata odczytuje wpis w App Store albo wpis w Google Play, gdy nie ma czytelnego linku do App Store, i importuje jego dane.

PoleOpis
overwriteOpcjonalne, domyślnie false. Przy wartości false uzupełniane są tylko puste pola, a zrzuty ekranu są dodawane tylko wtedy, gdy aplikacja nie ma żadnych. Przy wartości true zastępowane są nazwa, ikona, teksty i zrzuty ekranu. Ocena i cena są zawsze aktualizowane.
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 }'

Odpowiedź to obiekt aplikacji zawierający links i screenshots, a dodatkowo wysyłany jest webhook app.metadata_fetched. Jeśli nie da się odczytać żadnego wpisu:

HTTP/2 422
{
  "message": "The store listing could not be read. Add a valid App Store or Google Play link first.",
  "code": "metadata_unavailable"
}

Analityka

GET /apps/{id}/analytics przyjmuje te parametry zapytania:

ParametrOpis
range7d, 30d, 90d, 12m lub custom. Domyślnie 30d.
from, toDaty w formacie YYYY-MM-DD, obie włącznie, dla range=custom. to nie może być datą późniejszą niż dzisiejsza.
timezoneStrefa czasowa IANA, np. Europe/Istanbul, używana do wyznaczania granic dni. Domyślnie 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 jest uwzględniane, a to wykluczone. Oba są momentami w UTC.
  • clamped_to_plan ma wartość true, gdy żądany zakres został skrócony do historii dostępnej w planie.
  • daily liczy kliknięcia według lokalnej daty, łącznie z dniami bez kliknięć.
  • Podziały zawierają do 10 wartości, od najczęstszych. Pusty klucz "" oznacza wartość nieznaną lub nieustawioną.
  • Definicje wskaźników znajdziesz na stronie Analityka.

Kod QR

GET /apps/{id}/qr zwraca obraz. Użyj format=svg (domyślnie) lub format=png oraz tych samych opcji co w publicznych adresach URL kodów QR: fg, bg, margin, ecc, size, logo i download. Zobacz Kody QR i zestaw prasowy.

curl "https://mapps.one/api/v1/apps/01j8b2k6r3xq9v7m4n5p0s1t2w/qr?format=png&size=2048&ecc=Q" \
  -H "Authorization: Bearer $MAPPS_TOKEN" \
  -o habitly-qr.png

Przestrzeń robocza

GET /workspace zwraca przestrzeń roboczą, limity i funkcje jej planu, bieżące wykorzystanie oraz używany token. To dobre pierwsze wywołanie, aby sprawdzić, czy token działa.

{
  "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"] }
  }
}

Limit o wartości null oznacza brak limitu.

Typy zdarzeń

GET /events zwraca listę typów zdarzeń webhooków wraz z krótkim opisem. Integracje mogą z niego korzystać, aby zbudować pole wyboru zdarzeń.

{
  "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." }
  ]
}

Subskrypcje webhooków

Twórz subskrypcje webhooków z poziomu kodu, np. gdy użytkownik łączy konto z twoją integracją, i usuwaj je, gdy je rozłącza. POST /webhooks przyjmuje:

PoleWymaganeOpis
urlTakPubliczny adres URL https, który odbiera zdarzenia
eventsTakTablica typów zdarzeń lub ["*"] dla wszystkich zdarzeń
descriptionNieDo 160 znaków, wyświetlany w panelu
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"
  }
}

Sekret podpisu secret jest zwracany tylko przy tworzeniu subskrypcji. Używaj go do weryfikacji podpisów. Przestrzeń robocza w planie Studio może mieć do 10 endpointów webhooków. Subskrypcję usuniesz za pomocą DELETE /webhooks/{id}, które zwraca 204 No Content.

Przykład: publikowanie wersji beta z CI

Ten skrypt tworzy aplikację, dodaje jej link do Google Play, importuje wpis ze sklepu i wyświetla inteligentny link. Wymaga curl, jq i tokenu z uprawnieniem 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'

Wersjonowanie

To wersja 1 API. W każdej chwili możemy dodawać endpointy, pola i typy zdarzeń, więc ignoruj pola, których nie rozpoznajesz. Zmiany niezgodne wstecz zostaną wprowadzone jako nowa wersja z wcześniejszym powiadomieniem.