Mosavo
Se connecterCréer ma page
Développeurs

API Mosavo

Lis les pages publiques, gère ton compte depuis tes outils et automatise Mosavo avec une API JSON simple.

Sommaire

Introduction

L'API est servie sous /api/v1. Toutes les réponses sont en JSON et toutes les dates sont au format ISO 8601 en UTC. Elle a trois niveaux d'accès.

  • API publique. Sans clé, en lecture seule, uniquement pour ce qui est déjà visible publiquement sur Mosavo.
  • API personnelle. Avec une clé personnelle, pour lire et modifier les données de ton propre compte, selon les portées de la clé.
  • API d'administration. Avec une clé d'administration, créée par un administrateur, pour accéder à tout.
curl https://mosavo.fr/api/v1/status

Authentification

Envoie ta clé dans l'en tête Authorization, précédée de Bearer. Les clés ne sont jamais acceptées dans l'adresse de la requête, et les cookies de session du site ne sont pas acceptés par l'API.

curl https://mosavo.fr/api/v1/me \
  -H "Authorization: Bearer msk_your_key"

Clés personnelles

Crée tes clés dans Paramètres, API. Elles commencent par msk_ et demandent une adresse email vérifiée. Choisis les portées utiles, une restriction d'IP, une expiration et, si besoin, des limites plus basses que celles de ton compte. La clé n'est affichée qu'une fois.

Clés d'administration

Elles commencent par msk_admin_ et ne peuvent être créées que par un administrateur, avec la double authentification active. Chaque appel est journalisé et une alerte est envoyée quand une clé est utilisée depuis une nouvelle adresse IP.

Clés refusées

Une clé est refusée si elle est révoquée ou expirée, si l'adresse IP n'est pas autorisée, si le compte est suspendu ou si son email n'est pas vérifié. Une clé d'administration se coupe d'elle même quand son créateur n'est plus administrateur.

Limites

Chaque compte a un nombre de requêtes par minute et par jour. Sans clé, la limite s'applique par adresse IP. Les compteurs par jour se remettent à zéro à minuit UTC.

CompteRequêtes par minuteRequêtes par jourClés maxWebhooks
Sans clé, par IP301 000AucuneAucune
Gratuit vérifié605 00021
Étudiant12020 00053
Premium300100 0001010
Entreprise vérifiée600500 0002025
Staff ou admin1 000Illimité20Illimité

Chaque réponse indique la limite la plus proche d'être atteinte. Au delà, l'API répond 429 avec l'en tête Retry-After, en secondes.

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1793361660
X-Request-Id: 6f1c0a2e-…

Erreurs

En cas d'erreur, l'API répond avec un code HTTP adapté et un objet error. Le champ code est stable et peut être utilisé dans ton code ; le message, en anglais, est destiné aux développeurs. Cite l'en tête X-Request-Id si tu contactes le support.

{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key is missing the required scope: profile:read.",
    "details": { "required": "profile:read" }
  }
}
CodeSignification
unauthorizedClé absente ou en tête Authorization mal formé.
invalid_keyLa clé n'existe pas.
key_revokedLa clé a été révoquée.
key_expiredLa clé a expiré.
session_not_acceptedUn cookie de session a été envoyé à la place d'une clé.
forbiddenAction interdite pour ce compte.
limit_reachedLimite de ton offre atteinte (pages, tickets ouverts…).
insufficient_scopeLa clé n'a pas la portée demandée par la route.
ip_not_allowedL'adresse IP n'est pas autorisée pour cette clé.
email_unverifiedL'email du compte n'est pas vérifié.
account_bannedLe compte est suspendu.
not_foundRessource ou route introuvable.
conflictConflit : adresse déjà prise, modification concurrente ou clé d'idempotence réutilisée.
validation_failedParamètres invalides, le détail est dans details.
rate_limitedLimite atteinte, réessaie après Retry-After.
feature_disabledCette partie de l'API est coupée pour le moment.
internal_errorErreur inattendue côté Mosavo.

Pagination

Les listes sont paginées par curseur. Le paramètre limit vaut 20 par défaut et 100 au maximum. Pour la page suivante, renvoie la valeur de meta.nextCursor dans le paramètre cursor. Elle vaut null sur la dernière page.

{
  "data": [ … ],
  "meta": { "nextCursor": "eyJpZCI6ImNseDEifQ", "limit": 20 }
}

Les dates sont toujours au format ISO 8601 en UTC, par exemple 2026-10-30T12:00:00.000Z.

Portées

Une clé personnelle n'accède qu'aux routes couvertes par ses portées. Les clés d'administration ont accès à tout.

PortéeGroupeAccès
profile:readProfilLire le profil
profile:writeProfilModifier le profil
pages:readPagesLire les pages
pages:writePagesModifier les pages
blocks:readBlocsLire les blocs
blocks:writeBlocsModifier les blocs
projects:readProjetsLire les projets
projects:writeProjetsModifier les projets
analytics:readStatistiquesLire les statistiques
messages:readMessagesLire les messages reçus
messages:writeMessagesGérer les messages reçus
followers:readAbonnementsVoir les abonnés
follows:writeAbonnementsSuivre et ne plus suivre
notifications:readNotificationsLire les notifications
notifications:writeNotificationsMarquer les notifications
teams:readÉquipesLire les équipes
teams:writeÉquipesGérer les équipes
domains:readDomainesLire les domaines
domains:writeDomainesGérer les domaines
webhooks:readWebhooksLire les webhooks et leurs livraisons
webhooks:writeWebhooksGérer les webhooks
support:readSupportLire les demandes
support:writeSupportÉcrire au support
export:readExportExporter les données

Les anciennes portées portfolios:read et portfolios:write restent acceptées : elles équivalent aux portées pages, blocks et projects correspondantes.

Écriture

Avec une clé personnelle qui porte les portées :write, tu peux créer, modifier et supprimer tes pages, leurs blocs et leurs projets, publier ou dépublier une page, gérer tes messages reçus, tes abonnements, tes notifications, tes tickets de support et ton profil public. Les anciennes portées portfolios:write restent valables pour les pages, blocs et projets. Avec teams:write, tu crées et gères tes équipes (nom, marque, invitations, rôles, départ) ; avec domains:write, tu ajoutes, vérifies et retires le domaine d'une page : la réponse liste les enregistrements DNS à créer, sans le jeton de vérification, à copier depuis le tableau de bord. Avec webhooks:write, tu gères tes webhooks (voir le guide des webhooks).

POST crée une ressource et répond 201, PATCH modifie seulement les champs envoyés, PUT remplace une disposition ou un état complet, DELETE supprime. Les corps sont en JSON (Content-Type: application/json) et validés strictement : un champ inconnu ou invalide renvoie validation_failed avec le détail.

curl -X PATCH "https://mosavo.fr/api/v1/me/pages/<id>" \
  -H "Authorization: Bearer msk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"title":"Ada Lovelace","tags":["math"]}'

Les règles sont celles du tableau de bord : validation du catalogue des blocs, 60 blocs au plus par page, limites de ton offre (limit_reached), rôle requis pour les pages d'équipe. Chaque modification vide le cache de la page publique, enregistre une révision et déclenche les mêmes notifications et annonces Discord que l'interface.

L'administration peut couper l'écriture par l'API personnelle : les routes concernées répondent alors feature_disabled, la lecture continue de fonctionner.

Idempotence

Sur les requêtes POST, ajoute l'en tête facultatif Idempotency-Key avec une valeur unique (un UUID par exemple). Si la requête est renvoyée avec la même clé et le même corps dans les 24 heures, l'API rejoue la première réponse sans agir une deuxième fois, avec l'en tête Idempotent-Replayed: true.

curl -X POST "https://mosavo.fr/api/v1/me/pages" \
  -H "Authorization: Bearer msk_your_key" \
  -H "Idempotency-Key: 8f14e45f-ceea-4e7a-9c5b-2f1a6c3d9b10" \
  -H "Content-Type: application/json" \
  -d '{"slug":"ada","title":"Ada Lovelace"}'

La même clé avec un autre corps, ou pendant que la première requête est encore en cours, répond conflict. Une erreur serveur libère la clé pour que tu puisses réessayer.

Administration

Les clés d'administration lisent les comptes (recherche et fiche sans aucun secret), les pages, les équipes, les signalements, les alertes de modération, les tickets, les incidents, le journal d'audit et les statistiques. Elles peuvent traiter un signalement, confirmer ou écarter une alerte, dépublier une page, bannir ou débannir un compte avec un motif, répondre à un ticket et changer son statut.

Chaque action est écrite dans le journal d'audit au nom du créateur de la clé, avec la mention clé admin et le nom de la clé, et part dans les journaux Discord comme depuis l'interface.

Restent réservés à l'interface, avec la double authentification : rôles et permissions du staff, gestion des clés d'administration, connexion en tant qu'un membre, sauvegardes, suppression définitive d'un compte, réglages du site et interrupteurs.

Client TypeScript

Le dépôt fournit @mosavo/api-client, un petit client typé sans dépendance : il envoie la clé en Bearer, renvoie le contenu de data, lève une MosavoApiError avec le code stable, le statut et l'identifiant de requête, parcourt les listes avec le curseur et réessaie automatiquement après un 429 en respectant Retry-After.

import { createMosavoClient, isMosavoApiError } from "@mosavo/api-client"

const mosavo = createMosavoClient({ baseUrl: "https://mosavo.fr", apiKey: process.env.MOSAVO_KEY })

const page = await mosavo.post<{ id: string }>("/api/v1/me/pages", { slug: "ada", title: "Ada" }, { idempotencyKey: crypto.randomUUID() })
for await (const follower of mosavo.paginate("/api/v1/me/followers")) console.log(follower)

try {
  await mosavo.post(`/api/v1/me/pages/${page.id}/publish`)
} catch (error) {
  if (isMosavoApiError(error)) console.error(error.code, error.requestId)
}

Le bot Discord de Mosavo l'utilise pour la commande /profile quand une clé d'administration lui est fournie.