Pular para o conteúdo

Desenvolvedores

Referência da API

A API REST do mapps.one permite criar e atualizar apps, gerenciar links da loja, importar metadados da loja, ler análises, gerar códigos QR e se inscrever em webhooks a partir do seu próprio código, pipeline de CI ou integração. A API está disponível no plano Studio.

URL base

https://mapps.one/api/v1

Todas as solicitações usam HTTPS. Envie os corpos das solicitações em JSON com Content-Type: application/json e sempre envie Accept: application/json para que os erros também sejam retornados em JSON.

Autenticação

Crie um token no painel, em Desenvolvedores. Proprietários e admins do espaço de trabalho podem fazer isso. Dê um nome ao token, como "GitHub Actions", e escolha as permissões dele. O token é exibido apenas uma vez, então guarde-o no seu gerenciador de segredos imediatamente.

Os tokens pertencem ao espaço de trabalho, não a uma pessoa, então continuam funcionando quando alguém sai da equipe. Eles não expiram. Revogue um token na mesma página quando não precisar mais dele ou se ele puder ter vazado.

Envie o token como bearer token:

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

Permissões

PermissãoPermite
apps:readListar e ler apps, baixar códigos QR
apps:writeCriar, atualizar e excluir apps, substituir links da loja, importar metadados da loja
analytics:readLer as análises dos apps
webhooks:manageListar, criar e excluir inscrições de webhook

GET /workspace e GET /events funcionam com qualquer token válido. Dê a cada integração apenas as permissões de que ela precisa.

Convenções

  • Os IDs são ULIDs de 26 caracteres em minúsculas, como 01j8b2k6r3xq9v7m4n5p0s1t2w. Os apps são identificados pelo id, não pelo slug, então renomear um slug nunca quebra sua integração.
  • Os timestamps seguem a ISO 8601 em UTC, como 2026-09-14T08:12:44+00:00.
  • As respostas envolvem o resultado em uma chave data.
  • As chaves de loja são app_store, google_play, app_gallery, microsoft_store e web.
  • As chaves de plataforma são ios, android, huawei, windows, macos e other. As chaves de destino são as chaves de loja mais landing.

Limites de taxa

Cada espaço de trabalho pode fazer 120 solicitações por minuto, compartilhadas entre todos os seus tokens. Toda resposta inclui os cabeçalhos X-RateLimit-Limit e X-RateLimit-Remaining. Quando você ultrapassa o limite, a API responde com 429 Too Many Requests e um cabeçalho Retry-After com o número de segundos que você deve aguardar.

Erros

Os erros retornam um corpo JSON com uma message legível por humanos. Alguns erros também incluem um code legível por máquinas, e os erros de validação listam os problemas por campo em errors.

StatusQuando
401O token está ausente, é inválido ou foi revogado. {"message": "Unauthenticated."}
402O plano do espaço de trabalho não inclui acesso à API. Código plan_required.
403O token não tem a permissão exigida por este endpoint. {"message": "Invalid ability provided."}
404O app ou a inscrição não existe, ou pertence a outro espaço de trabalho.
422A validação falhou ou a solicitação não pôde ser concluída. Por exemplo, código metadata_unavailable.
429Limite de taxa excedido. Aguarde o número de segundos indicado em Retry-After.
5xxAlgo deu errado do nosso lado. Tente novamente com backoff exponencial.
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."]
  }
}

Endpoints

Método e caminhoPermissãoDescrição
GET /workspacequalquerEspaço de trabalho, plano, uso e o token atual
GET /eventsqualquerTipos de evento de webhook
GET /appsapps:readListar apps
POST /appsapps:writeCriar um app
GET /apps/{id}apps:readObter um app
PATCH /apps/{id}apps:writeAtualizar um app
DELETE /apps/{id}apps:writeExcluir um app
PUT /apps/{id}/linksapps:writeDefinir ou remover links da loja
POST /apps/{id}/metadataapps:writeImportar detalhes da ficha da loja
GET /apps/{id}/analyticsanalytics:readTotais, série diária e detalhamentos
GET /apps/{id}/qrapps:readImagem do código QR
GET /webhookswebhooks:manageListar inscrições de webhook
POST /webhookswebhooks:manageCriar uma inscrição de webhook
DELETE /webhooks/{id}webhooks:manageExcluir uma inscrição de webhook

O objeto app

CampoTipoDescrição
idstringULID do app
namestringNome do app
slugstringO caminho do link inteligente: mapps.one/{slug}
statusstringlive, paused ou suspended
tagline, descriptionstring ou nullTextos da página
categorystring ou nullUma chave de categoria, como health-fitness ou productivity
page_themestringclean, midnight ou vivid
accent_colorstring ou nullCor hexadecimal, como #16a34a
developerobjectname, website e email
social_linksobjectPerfis sociais preenchidos, indexados por rede: x, instagram, tiktok, youtube, facebook, linkedin, threads, github, discord, reddit
featuresarrayItens de recurso com icon, title e description
listed_in_explorebooleanSe o app aparece no Explore
utm_passthroughbooleanSe as tags UTM são repassadas às lojas
redirect_rulesobjectDestino por plataforma, com os valores padrão preenchidos
icon_urlstring ou nullURL pública do ícone
ratingobject ou nullvalue e count da loja
urlsobjectURLs públicas: smart_link, landing_page, qr_svg, qr_png, privacy_policy, terms. As URLs jurídicas retornam 404 até que o documento seja publicado.
linksobjectLinks da loja indexados por loja, cada um com url, status (unverified, verified ou invalid) e verified_at. Incluído nas respostas de um único app.
screenshotsarrayCapturas de tela com url, width e height. Incluído depois de uma importação de metadados.
created_at, updated_atstringTimestamps ISO 8601

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

Listar apps

Retorna os apps do espaço de trabalho. Os resultados são paginados: siga links.next, ou passe ?page=2, até que ele seja 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
  }
}

Os objetos app estão abreviados neste exemplo. Cada item tem o conjunto completo de campos.

Criar um app

CampoObrigatórioDescrição
nameSimNome do app, com até 120 caracteres
slugNãoDe 3 a 40 letras minúsculas, números e hifens simples. Quando omitido, um slug livre é gerado a partir do nome.
linksNãoLinks da loja indexados por loja, no mesmo formato de Definir links da loja

Você também pode enviar qualquer um dos campos listados em Atualizar um 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"
    }
  }'

A resposta é 201 Created com o novo objeto app. Os links da loja são salvos na forma canônica com o status unverified até que a verificação em segundo plano termine. Para preencher o ícone, as capturas de tela e a descrição, chame Importar metadados da loja em seguida.

Atualizar um app

Envie apenas os campos que você quer alterar.

CampoTipo
namestring
slugstring. Alterá-lo quebra o link antigo imediatamente.
tagline, descriptionstring ou null
categorychave de categoria ou null
page_themeclean, midnight ou vivid
accent_color#rrggbb ou null
utm_passthrough, listed_in_exploreboolean
redirect_rulesobjeto que associa chaves de plataforma a chaves de destino
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" }
  }'

A resposta é o objeto app atualizado.

Excluir um app

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

A resposta é 204 No Content. A exclusão é permanente: o link inteligente, a página de destino, os documentos jurídicos, as mídias e as análises do app são removidos.

PUT /apps/{id}/links recebe um objeto links indexado por loja:

  • uma URL adiciona ou substitui o link dessa loja,
  • null ou uma string vazia remove o link,
  • as lojas que você não incluir não são alteradas.

Cada URL deve ser uma ficha válida da respectiva loja: um link apps.apple.com com um ID de app, um link play.google.com com um ID de pacote, e assim por diante. O link web pode ser qualquer endereço http ou https. As URLs podem ter até 1024 caracteres. Os links são salvos na forma canônica e verificados em segundo plano.

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

A resposta é o objeto app, incluindo links. Um link inválido retorna 422:

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

Importar metadados da loja

POST /apps/{id}/metadata lê a ficha da App Store, ou a ficha do Google Play quando não há um link da App Store legível, e importa os detalhes dela.

CampoDescrição
overwriteOpcional, padrão false. Quando false, apenas os campos vazios são preenchidos, e as capturas de tela só são adicionadas se o app não tiver nenhuma. Quando true, o nome, o ícone, os textos e as capturas de tela são substituídos. A avaliação e o preço são sempre atualizados.
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 }'

A resposta é o objeto app, incluindo links e screenshots, e um webhook app.metadata_fetched é enviado. Se nenhuma ficha puder ser lida:

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

Análises

GET /apps/{id}/analytics aceita estes parâmetros de consulta:

ParâmetroDescrição
range7d, 30d, 90d, 12m ou custom. Padrão 30d.
from, toDatas no formato YYYY-MM-DD, ambas incluídas, para range=custom. to não pode ser posterior a hoje.
timezoneUm fuso horário IANA, como Europe/Istanbul, usado para os limites dos dias. Padrão 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 é incluído e to é excluído. Ambos são instantes em UTC.
  • clamped_to_plan é true quando o período solicitado foi encurtado para caber no histórico do plano.
  • daily conta os cliques por data local, incluindo dias sem cliques.
  • Os detalhamentos listam até 10 valores, dos mais frequentes para os menos frequentes. Uma chave vazia "" significa desconhecido ou não definido.
  • As definições das métricas estão na página Análises.

Código QR

GET /apps/{id}/qr retorna uma imagem. Use format=svg (padrão) ou format=png, além das mesmas opções das URLs públicas de QR: fg, bg, margin, ecc, size, logo e download. Veja Códigos QR e kit de imprensa.

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

Espaço de trabalho

GET /workspace retorna o espaço de trabalho, os limites e recursos do plano, o uso atual e o token em uso. É uma boa primeira chamada para verificar se um token funciona.

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

Um limite null significa ilimitado.

Tipos de evento

GET /events lista os tipos de evento de webhook com uma descrição curta. As integrações podem usá-lo para montar um seletor de eventos.

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

Inscrições de webhook

Crie inscrições de webhook a partir do código, por exemplo quando um usuário conecta sua integração, e exclua-as quando ele se desconectar. POST /webhooks recebe:

CampoObrigatórioDescrição
urlSimUma URL https pública que recebe os eventos
eventsSimUm array de tipos de evento, ou ["*"] para todos os eventos
descriptionNãoAté 160 caracteres, exibida no painel
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"
  }
}

O secret de assinatura só é retornado quando a inscrição é criada. Use-o para verificar assinaturas. Um espaço de trabalho Studio pode ter até 10 endpoints de webhook. Exclua uma inscrição com DELETE /webhooks/{id}, que retorna 204 No Content.

Exemplo: publicar uma versão beta pelo CI

Este script cria um app, adiciona o link do Google Play dele, importa a ficha e imprime o link inteligente. Ele precisa de curl, jq e de um token com 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'

Versionamento

Esta é a versão 1 da API. Podemos adicionar endpoints, campos e tipos de evento a qualquer momento, então ignore os campos que você não reconhecer. Mudanças incompatíveis serão lançadas como uma nova versão, com aviso prévio.