Vai al contenuto

Sviluppatori

Riferimento API

La REST API di mapps.one ti permette di creare e aggiornare app, gestire i link agli store, importare i metadati degli store, leggere le statistiche, generare codici QR e registrare webhook dal tuo codice, dalla tua pipeline CI o dalla tua integrazione. L'API è disponibile con il piano Studio.

URL di base

https://mapps.one/api/v1

Tutte le richieste usano HTTPS. Invia i corpi delle richieste in JSON con Content-Type: application/json, e invia sempre Accept: application/json, così anche gli errori vengono restituiti in JSON.

Autenticazione

Crea un token nella dashboard, nella sezione Sviluppatori. Possono farlo i proprietari e gli admin del workspace. Dai al token un nome, come "GitHub Actions", e scegli i suoi permessi. Il token viene mostrato una sola volta, quindi salvalo subito nel tuo gestore di segreti.

I token appartengono al workspace, non a una persona, quindi continuano a funzionare quando qualcuno lascia il team. Non scadono. Revoca un token dalla stessa pagina quando non ti serve più, o se potrebbe essere stato divulgato.

Invia il token come bearer token:

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

Permessi

PermessoConsente di
apps:readElencare e leggere le app, scaricare i codici QR
apps:writeCreare, aggiornare ed eliminare app, sostituire i link agli store, importare i metadati degli store
analytics:readLeggere le statistiche delle app
webhooks:manageElencare, creare ed eliminare le sottoscrizioni webhook

GET /workspace e GET /events funzionano con qualsiasi token valido. Assegna a ogni integrazione solo i permessi di cui ha bisogno.

Convenzioni

  • Gli ID sono ULID di 26 caratteri minuscoli, come 01j8b2k6r3xq9v7m4n5p0s1t2w. Le app vengono identificate tramite id, non tramite slug, quindi rinominare uno slug non rompe mai la tua integrazione.
  • I timestamp sono in formato ISO 8601 in UTC, come 2026-09-14T08:12:44+00:00.
  • Le risposte racchiudono il risultato in una chiave data.
  • Le chiavi degli store sono app_store, google_play, app_gallery, microsoft_store e web.
  • Le chiavi delle piattaforme sono ios, android, huawei, windows, macos e other. Le chiavi delle destinazioni sono le chiavi degli store più landing.

Limiti di richieste

Ogni workspace può effettuare 120 richieste al minuto, condivise tra tutti i suoi token. Ogni risposta include gli header X-RateLimit-Limit e X-RateLimit-Remaining. Quando superi il limite, l'API risponde con 429 Too Many Requests e un header Retry-After con il numero di secondi da attendere.

Errori

Gli errori restituiscono un corpo JSON con un message leggibile. Alcuni errori includono anche un code interpretabile da un programma, e gli errori di validazione elencano i problemi per campo in errors.

StatoQuando
401Il token manca, non è valido o è stato revocato. {"message": "Unauthenticated."}
402Il piano del workspace non include l'accesso all'API. Codice plan_required.
403Il token non ha il permesso richiesto da questo endpoint. {"message": "Invalid ability provided."}
404L'app o la sottoscrizione non esiste, oppure appartiene a un altro workspace.
422La validazione non è riuscita, oppure non è stato possibile completare la richiesta. Ad esempio, codice metadata_unavailable.
429Limite di richieste superato. Attendi il numero di secondi indicato in Retry-After.
5xxSi è verificato un problema da parte nostra. Riprova con un backoff esponenziale.
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."]
  }
}

Endpoint

Metodo e percorsoPermessoDescrizione
GET /workspacequalsiasiWorkspace, piano, utilizzo e token corrente
GET /eventsqualsiasiTipi di evento dei webhook
GET /appsapps:readElenca le app
POST /appsapps:writeCrea un'app
GET /apps/{id}apps:readRecupera un'app
PATCH /apps/{id}apps:writeAggiorna un'app
DELETE /apps/{id}apps:writeElimina un'app
PUT /apps/{id}/linksapps:writeImposta o rimuovi i link agli store
POST /apps/{id}/metadataapps:writeImporta i dettagli dalla scheda dello store
GET /apps/{id}/analyticsanalytics:readTotali, serie giornaliera e suddivisioni
GET /apps/{id}/qrapps:readImmagine del codice QR
GET /webhookswebhooks:manageElenca le sottoscrizioni webhook
POST /webhookswebhooks:manageCrea una sottoscrizione webhook
DELETE /webhooks/{id}webhooks:manageElimina una sottoscrizione webhook

L'oggetto app

CampoTipoDescrizione
idstringaULID dell'app
namestringaNome dell'app
slugstringaIl percorso dello smart link: mapps.one/{slug}
statusstringalive, paused o suspended
tagline, descriptionstringa o nullTesto della pagina
categorystringa o nullUna chiave di categoria, come health-fitness o productivity
page_themestringaclean, midnight o vivid
accent_colorstringa o nullColore esadecimale, come #16a34a
developeroggettoname, website ed email
social_linksoggettoProfili social compilati, con il social network come chiave: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit
featuresarrayElementi delle funzionalità con icon, title e description
listed_in_explorebooleanoIndica se l'app compare in Esplora
utm_passthroughbooleanoIndica se i tag UTM vengono inoltrati agli store
redirect_rulesoggettoDestinazione per piattaforma, con i valori predefiniti già compilati
icon_urlstringa o nullURL pubblico dell'icona
ratingoggetto o nullvalue e count dallo store
urlsoggettoURL pubblici: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. Gli URL legali restituiscono 404 finché il documento non viene pubblicato.
linksoggettoLink agli store con lo store come chiave, ciascuno con url, status (unverified, verified o invalid) e verified_at. Inclusi nelle risposte relative a una singola app.
screenshotsarrayScreenshot con url, width e height. Inclusi dopo un'importazione dei metadati.
created_at, updated_atstringaTimestamp ISO 8601

Recupera un'app

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

Elenca le app

Restituisce le app del workspace. I risultati sono paginati: segui links.next, oppure passa ?page=2, finché non è 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
  }
}

In questo esempio gli oggetti app sono abbreviati. Ogni elemento contiene l'insieme completo dei campi.

Crea un'app

CampoObbligatorioDescrizione
nameSìNome dell'app, fino a 120 caratteri
slugNoDa 3 a 40 caratteri tra lettere minuscole, numeri e trattini singoli. Se omesso, viene generato uno slug libero a partire dal nome.
linksNoLink agli store con lo store come chiave, nello stesso formato di Imposta i link agli store

Puoi inviare anche uno qualsiasi dei campi elencati in Aggiorna un'app.

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

La risposta è 201 Created con il nuovo oggetto app. I link agli store vengono salvati in forma canonica con lo stato unverified finché non termina il controllo in background. Per compilare icona, screenshot e descrizione, chiama poi Importa i metadati dello store.

Aggiorna un'app

Invia solo i campi che vuoi modificare.

CampoTipo
namestringa
slugstringa. Modificarlo rompe subito il vecchio link.
tagline, descriptionstringa o null
categorychiave di categoria o null
page_themeclean, midnight o vivid
accent_color#rrggbb o null
utm_passthrough, listed_in_explorebooleano
redirect_rulesoggetto che associa una chiave di piattaforma a una chiave di destinazione
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" }
  }'

La risposta è l'oggetto app aggiornato.

Elimina un'app

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

La risposta è 204 No Content. L'eliminazione è definitiva: vengono rimossi smart link, landing page, documenti legali, contenuti multimediali e statistiche dell'app.

PUT /apps/{id}/links accetta un oggetto links con lo store come chiave:

  • un URL aggiunge o sostituisce il link per quello store,
  • null o una stringa vuota lo rimuove,
  • gli store che ometti non vengono modificati.

Ogni URL deve essere una scheda valida per il suo store: un link apps.apple.com con un ID dell'app, un link play.google.com con un ID del pacchetto e così via. Il link web può essere qualsiasi indirizzo http o https. Gli URL possono avere fino a 1024 caratteri. I link vengono salvati in forma canonica e controllati in background.

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

La risposta è l'oggetto app, incluso links. Un link non valido restituisce 422:

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

Importa i metadati dello store

POST /apps/{id}/metadata legge la scheda dell'App Store, oppure quella di Google Play quando non c'è un link dell'App Store leggibile, e ne importa i dettagli.

CampoDescrizione
overwriteFacoltativo, valore predefinito false. Se è false, vengono compilati solo i campi vuoti e gli screenshot vengono aggiunti solo se l'app non ne ha. Se è true, vengono sostituiti nome, icona, testi e screenshot. Valutazione e prezzo vengono sempre aggiornati.
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 }'

La risposta è l'oggetto app, inclusi links e screenshots, e viene inviato un webhook app.metadata_fetched. Se non è possibile leggere nessuna scheda:

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

Statistiche

GET /apps/{id}/analytics accetta questi parametri della query:

ParametroDescrizione
range7d, 30d, 90d, 12m o custom. Valore predefinito 30d.
from, toDate nel formato YYYY-MM-DD, entrambe incluse, per range=custom. to non può essere successiva a oggi.
timezoneUn fuso orario IANA, come Europe/Istanbul, usato per i limiti dei giorni. Valore predefinito 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 è incluso e to è escluso. Entrambi sono istanti in UTC.
  • clamped_to_plan è true quando l'intervallo richiesto è stato accorciato alla cronologia del piano.
  • daily conta i clic per data locale, inclusi i giorni senza clic.
  • Le suddivisioni elencano fino a 10 valori, a partire dai più frequenti. Una chiave vuota "" indica un valore sconosciuto o non impostato.
  • Le definizioni delle metriche sono nella pagina Statistiche.

Codice QR

GET /apps/{id}/qr restituisce un'immagine. Usa format=svg (predefinito) o format=png, più le stesse opzioni degli URL QR pubblici: fg, bg, margin, ecc, size, logo e download. Consulta Codici QR e press kit.

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

Workspace

GET /workspace restituisce il workspace, i limiti e le funzionalità del suo piano, l'utilizzo attuale e il token in uso. È una buona prima chiamata per verificare che un token funzioni.

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

Un limite null significa illimitato.

Tipi di evento

GET /events elenca i tipi di evento dei webhook con una breve descrizione. Le integrazioni possono usarlo per creare un selettore degli eventi.

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

Sottoscrizioni webhook

Crea le sottoscrizioni webhook dal codice, ad esempio quando un utente collega la tua integrazione, ed eliminale quando si scollega. POST /webhooks accetta:

CampoObbligatorioDescrizione
urlSìUn URL https pubblico che riceve gli eventi
eventsSìUn array di tipi di evento, oppure ["*"] per tutti gli eventi
descriptionNoFino a 160 caratteri, mostrata nella dashboard
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"
  }
}

Il secret di firma viene restituito solo quando la sottoscrizione viene creata. Usalo per verificare le firme. Un workspace Studio può avere fino a 10 endpoint webhook. Elimina una sottoscrizione con DELETE /webhooks/{id}, che restituisce 204 No Content.

Esempio: pubblicare una beta dalla CI

Questo script crea un'app, aggiunge il suo link a Google Play, importa la scheda e stampa lo smart link. Richiede curl, jq e un token con 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'

Versioni

Questa è la versione 1 dell'API. Potremmo aggiungere endpoint, campi e tipi di evento in qualsiasi momento, quindi ignora i campi che non riconosci. Le modifiche incompatibili verranno rilasciate come nuova versione, con un preavviso.