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
| Permesso | Consente di |
|---|---|
apps:read | Elencare e leggere le app, scaricare i codici QR |
apps:write | Creare, aggiornare ed eliminare app, sostituire i link agli store, importare i metadati degli store |
analytics:read | Leggere le statistiche delle app |
webhooks:manage | Elencare, 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 tramiteid, 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_storeeweb. - Le chiavi delle piattaforme sono
ios,android,huawei,windows,macoseother. 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.
| Stato | Quando |
|---|---|
401 | Il token manca, non è valido o è stato revocato. {"message": "Unauthenticated."} |
402 | Il piano del workspace non include l'accesso all'API. Codice plan_required. |
403 | Il token non ha il permesso richiesto da questo endpoint. {"message": "Invalid ability provided."} |
404 | L'app o la sottoscrizione non esiste, oppure appartiene a un altro workspace. |
422 | La validazione non è riuscita, oppure non è stato possibile completare la richiesta. Ad esempio, codice metadata_unavailable. |
429 | Limite di richieste superato. Attendi il numero di secondi indicato in Retry-After. |
5xx | Si è 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 percorso | Permesso | Descrizione |
|---|---|---|
GET /workspace | qualsiasi | Workspace, piano, utilizzo e token corrente |
GET /events | qualsiasi | Tipi di evento dei webhook |
GET /apps | apps:read | Elenca le app |
POST /apps | apps:write | Crea un'app |
GET /apps/{id} | apps:read | Recupera un'app |
PATCH /apps/{id} | apps:write | Aggiorna un'app |
DELETE /apps/{id} | apps:write | Elimina un'app |
PUT /apps/{id}/links | apps:write | Imposta o rimuovi i link agli store |
POST /apps/{id}/metadata | apps:write | Importa i dettagli dalla scheda dello store |
GET /apps/{id}/analytics | analytics:read | Totali, serie giornaliera e suddivisioni |
GET /apps/{id}/qr | apps:read | Immagine del codice QR |
GET /webhooks | webhooks:manage | Elenca le sottoscrizioni webhook |
POST /webhooks | webhooks:manage | Crea una sottoscrizione webhook |
DELETE /webhooks/{id} | webhooks:manage | Elimina una sottoscrizione webhook |
L'oggetto app
| Campo | Tipo | Descrizione |
|---|---|---|
id | stringa | ULID dell'app |
name | stringa | Nome dell'app |
slug | stringa | Il percorso dello smart link: mapps.one/{slug} |
status | stringa | live, paused o suspended |
tagline, description | stringa o null | Testo della pagina |
category | stringa o null | Una chiave di categoria, come health-fitness o productivity |
page_theme | stringa | clean, midnight o vivid |
accent_color | stringa o null | Colore esadecimale, come #16a34a |
developer | oggetto | name, website ed email |
social_links | oggetto | Profili social compilati, con il social network come chiave: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit |
features | array | Elementi delle funzionalità con icon, title e description |
listed_in_explore | booleano | Indica se l'app compare in Esplora |
utm_passthrough | booleano | Indica se i tag UTM vengono inoltrati agli store |
redirect_rules | oggetto | Destinazione per piattaforma, con i valori predefiniti già compilati |
icon_url | stringa o null | URL pubblico dell'icona |
rating | oggetto o null | value e count dallo store |
urls | oggetto | URL pubblici: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. Gli URL legali restituiscono 404 finché il documento non viene pubblicato. |
links | oggetto | Link 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. |
screenshots | array | Screenshot con url, width e height. Inclusi dopo un'importazione dei metadati. |
created_at, updated_at | stringa | Timestamp 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
| Campo | Obbligatorio | Descrizione |
|---|---|---|
name | Sì | Nome dell'app, fino a 120 caratteri |
slug | No | Da 3 a 40 caratteri tra lettere minuscole, numeri e trattini singoli. Se omesso, viene generato uno slug libero a partire dal nome. |
links | No | Link 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.
| Campo | Tipo |
|---|---|
name | stringa |
slug | stringa. Modificarlo rompe subito il vecchio link. |
tagline, description | stringa o null |
category | chiave di categoria o null |
page_theme | clean, midnight o vivid |
accent_color | #rrggbb o null |
utm_passthrough, listed_in_explore | booleano |
redirect_rules | oggetto 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.
Imposta i link agli store
PUT /apps/{id}/links accetta un oggetto links con lo store come chiave:
- un URL aggiunge o sostituisce il link per quello store,
nullo 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.
| Campo | Descrizione |
|---|---|
overwrite | Facoltativo, 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:
| Parametro | Descrizione |
|---|---|
range | 7d, 30d, 90d, 12m o custom. Valore predefinito 30d. |
from, to | Date nel formato YYYY-MM-DD, entrambe incluse, per range=custom. to non può essere successiva a oggi. |
timezone | Un 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 etoè escluso. Entrambi sono istanti in UTC.clamped_to_planètruequando l'intervallo richiesto è stato accorciato alla cronologia del piano.dailyconta 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:
| Campo | Obbligatorio | Descrizione |
|---|---|---|
url | Sì | Un URL https pubblico che riceve gli eventi |
events | Sì | Un array di tipi di evento, oppure ["*"] per tutti gli eventi |
description | No | Fino 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.