Vue d’ensemble
L’API Manilo est une API REST JSON qui permet de gérer par programme le registre que vous utilisez dans l’application iOS — comptes, catégories, budgets, groupes partagés et transactions. Servez-vous-en pour construire des imports, des exports, des passerelles de synchronisation, des tableaux de bord, ou pour alimenter vos propres automatisations.
- URL de base :
https://api.manilo.app— l’ancienne URL de baseapi.ledgy.appreste fonctionnelle. - Préfixe de version : tous les endpoints de ce document sont exposés sous
/api/v1/. - Transport : HTTPS uniquement. Les requêtes HTTP ne sont pas acceptées.
- Encodage : Corps de requête et de réponse en JSON. UTF-8. Noms de propriétés en
camelCase. - Authentification :
Authorization: Bearer …sur chaque requête. - Abonnement Cloud : requis sur chaque endpoint v1. Voir Contrôle d’abonnement.
https://api.manilo.app/mcp — voir Intégrations. L’API REST documentée ici s’adresse au code que vous écrivez vous-même.
Démarrage rapide
Trois étapes jusqu’à votre première requête authentifiée.
1. Générer un Personal Access Token
- Connectez-vous à votre tableau de bord Manilo et ouvrez Réglages → Accès API.
- Cliquez sur + Nouveau jeton.
- Donnez au jeton un nom explicite (par ex. « Zapier — export hebdomadaire »), choisissez les scopes dont vous avez besoin (voir Scopes) et, si vous le souhaitez, définissez une date d’expiration.
- Copiez le jeton. Il n’est affiché qu’une seule fois. Les jetons commencent par le préfixe
lgpat_suivi de 64 caractères hexadécimaux.
La même page liste vos jetons actifs avec leur date de dernière utilisation et leur nombre de permissions, affiche un avertissement « Expire dans 30 jours » et vous permet de révoquer un jeton instantanément via l’icône corbeille. Chaque compte peut détenir jusqu’à 25 jetons actifs simultanément.
2. Envoyer une requête
# Replace lgpat_… with your token curl "https://api.manilo.app/api/v1/accounts" \ -H "Authorization: Bearer lgpat_a1b2c3d4e5…"
3. Examiner la réponse
{
"items": [
{
"id": "acc_01HK8V…",
"name": "Wise EUR",
"currencyCode": "EUR",
"initialBalance": 1240.50,
"icon": "wallet",
"color": "#4A90E2",
"order": 0,
"createdAt": "2026-04-12T08:13:09Z",
"updatedAt": "2026-05-01T17:02:31Z"
}
],
"totalCount": 1
}
Authentification
Chaque requête vers /api/v1/ doit porter un en-tête Authorization. Deux types de jetons sont acceptés :
- Personal Access Token (PAT) — jeton bearer de longue durée que vous créez depuis la page Réglages → Accès API du tableau de bord. Format :
lgpat_+ 64 caractères hexadécimaux. Limité par scopes, révocable, avec expiration facultative. Recommandé pour toutes les intégrations tierces. - JWT de session — jeton de courte durée délivré aux applications propriétaires (iOS, tableau de bord). Il n’a aucune restriction de scope. Vous pouvez l’utiliser pour un test ponctuel si vous parvenez à en extraire un depuis une session connectée, mais les PAT restent la voie prise en charge.
Format de l’en-tête
Authorization: Bearer lgpat_a1b2c3d4e5f6…
Limites des jetons
- Jusqu’à 25 PAT actifs par compte Manilo.
- Une date d’expiration facultative peut être définie à la création. Les jetons expirés renvoient
401 Unauthorized. - Les jetons révoqués cessent de fonctionner immédiatement — Manilo ne conserve qu’un hachage SHA-256 du jeton, jamais sa valeur : un jeton divulgué ne peut donc pas être récupéré, seulement révoqué et remplacé.
Échecs d’authentification courants
- 401
- Jeton absent, mal formé, expiré ou révoqué.
- 403
- Le jeton est valide, mais l’endpoint demandé exige un scope que votre PAT ne possède pas, ou votre abonnement Cloud n’est pas actif.
Scopes
Les PAT suivent un modèle de refus par défaut. Un jeton ne peut appeler que les endpoints dont il détient le scope requis ; tout le reste renvoie 403 Forbidden. N’accordez que le jeu de scopes le plus restreint dont votre intégration a réellement besoin.
Scopes disponibles :
accounts:read
accounts:write
categories:read
categories:write
budgets:read
budgets:write
groups:read
groups:write
transactions:read
transactions:write
tags:read
tags:write
recurring:read
recurring:write
settings:read
settings:write
Chaque endpoint listé ci-dessous affiche le scope qu’il exige sous forme de petite pastille violette. Les scopes :write n’impliquent pas :read — demandez les deux si vous avez besoin des deux.
Contrôle d’abonnement
Tous les endpoints v1 — y compris ceux en lecture seule — exigent que l’utilisateur appelant dispose d’un abonnement Manilo Cloud actif. Si l’abonnement a été résilié, a expiré ou n’a jamais été souscrit, l’API répond :
HTTP/1.1 403 Forbidden
X-Subscription-Required: true
Content-Type: application/json
{ "error": "Active cloud subscription required" }
L’en-tête X-Subscription-Required permet aux clients de distinguer un blocage lié à l’abonnement d’un refus de permission générique. Rétablissez l’accès en réactivant Cloud dans l’application iOS ou sur dashboard.manilo.app/upgrade.
Erreurs
Les erreurs utilisent les codes de statut HTTP standard. Le corps de la réponse est un objet JSON à un seul champ :
{ "error": "Human-readable message" }
Codes de statut que vous devez gérer :
- 200
- OK — ressource renvoyée, ou liste renvoyée.
- 201
- Created — nouvelle ressource créée. L’en-tête
Locationpointe vers l’URL canonique. - 204
- No Content — suppression réussie ; aucun corps de réponse.
- 400
- Échec de la validation — champ requis manquant, valeur hors limites, JSON mal formé.
- 401
- Échec de l’authentification — voir Authentification.
- 403
- Permission refusée — scope insuffisant ou abonnement inactif.
- 404
- Ressource introuvable, ou masquée par les règles d’autorisation.
- 409
- Conflit — par ex. violation d’une contrainte d’unicité.
- 5xx
- Défaillance côté serveur. Vous pouvez réessayer sans risque les lectures idempotentes avec un backoff exponentiel.
Pagination et filtres
Par défaut, les endpoints de liste renvoient tous les éléments correspondants. Les transactions, seule ressource susceptible de devenir volumineuse, prennent en charge une pagination par curseur.
Curseur des transactions
curl "https://api.manilo.app/api/v1/transactions?limit=50&type=expense&dateFrom=2026-01-01" \ -H "Authorization: Bearer lgpat_…"
La réponse contient un nextCursor. Renvoyez-le dans le paramètre de requête cursor pour obtenir la page suivante ; lorsque nextCursor vaut null, vous avez atteint la fin.
limit— taille de page, bornée à1..200. Par défaut50.cursor— jeton opaque. Traitez-le comme une boîte noire.type,dateFrom,dateTo,categoryId,accountId,groupId— filtres facultatifs ; voir l’endpoint Lister les transactions.
Types et formats
- ID — chaînes opaques. Ne les analysez pas ; traitez-les comme des identifiants UTF-8 sensibles à la casse.
- Horodatages — ISO-8601 en UTC, avec un
Zfinal, par ex."2026-05-13T10:30:00Z". - Dates (par ex. le champ
dated’une transaction) — même forme ISO-8601, mais seule la partie date est significative. - Montants — nombres JSON exprimés en unités principales, avec jusqu’à 4 décimales (par ex.
12.50). Jamais en sous-unités. Toujours accompagnés decurrencyCode. - Codes devise — ISO-4217, exactement trois lettres majuscules (par ex.
"EUR","USD","GBP"). - Suppressions — toutes les opérations de suppression sont des suppressions logiques. Les éléments supprimés cessent d’apparaître dans les réponses de liste et de lecture ; les partenaires de partage et les reçus historiques sont conservés.
- Effets de bord — supprimer un compte, une catégorie ou un groupe laisse intactes les transactions qui en dépendent ; leurs références sont simplement détachées. L’endpoint Supprimer un compte accepte une stratégie explicite.
Comptes
Les comptes sont les enveloppes qui portent les soldes — un compte bancaire, une carte de crédit, un portefeuille d’espèces, un compte-titres. Chaque transaction est rattachée à l’un d’eux (ou à deux, dans le cas des virements).
/api/v1/accounts
accounts:read
Renvoie tous les comptes que l’utilisateur authentifié possède ou auxquels il a accès.
/api/v1/accounts/{id}
accounts:read
Récupère un compte par son id. Renvoie 404 s’il est introuvable.
/api/v1/accounts
accounts:write
Crée un compte. Renvoie 201 avec l’objet créé ainsi qu’un en-tête Location.
| Champ | Type | Description |
|---|---|---|
| name | string | requisNom affiché. 100 caractères max. |
| currencyCode | string | requisISO-4217. Exactement 3 lettres. |
| initialBalance | number | requisSolde d’ouverture, exprimé en currencyCode. |
| order | integer | requisPosition de tri. Les valeurs les plus basses viennent en premier. |
| icon | string | facultatifIdentifiant d’icône issu de /api/v1/icons. 50 max. |
| color | string | facultatifCouleur hexadécimale, par ex. "#4A90E2". 20 max. |
| iconColor | string | facultatifRemplace la teinte de l’icône. |
POST /api/v1/accounts
{
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E"
}
{
"id": "acc_01HK8V…",
"name": "Cash",
"currencyCode": "EUR",
"initialBalance": 50.00,
"order": 2,
"icon": "wallet",
"color": "#22C55E",
"iconColor": null,
"shareInviteToken": null,
"createdAt": "2026-05-13T10:30:00Z",
"updatedAt": "2026-05-13T10:30:00Z"
}
/api/v1/accounts/{id}
accounts:write
Remplace un compte existant. Le corps est identique à Créer ; tous les champs doivent être fournis.
/api/v1/accounts/{id}
accounts:write
Supprime logiquement un compte. Décidez du sort de ses transactions via le paramètre de requête action.
| Champ | Type | Description |
|---|---|---|
| action | enum | facultatifDetach (par défaut) : efface la référence au compte sur chaque transaction. Move : réaffecte les transactions à moveTargetAccountId. DeleteAll : supprime logiquement toutes les transactions liées dont vous êtes propriétaire. |
| moveTargetAccountId | string | facultatifObligatoire lorsque action=Move. Id du compte de destination. |
Catégories
Les catégories indiquent à quoi correspond une transaction (courses, loyer, revenus en freelance). Les catégories système sont en lecture seule et communes à tous les utilisateurs ; les catégories utilisateur, elles, vous appartiennent. Les groupes de catégories rassemblent les catégories apparentées.
/api/v1/categories/system-categories
categories:read
Renvoie le jeu de catégories « bien connues » sélectionné par Manilo — l’ensemble de départ livré avec l’application iOS. Il est versionné globalement et peut être mis en cache sans risque en s’appuyant sur version.
Catégories utilisateur
/api/v1/categories
categories:read
Liste toutes les catégories définies par l’utilisateur.
/api/v1/categories/{id}
categories:read
Récupère une catégorie utilisateur par son id.
/api/v1/categories
categories:write
Crée une catégorie utilisateur.
| Champ | Type | Description |
|---|---|---|
| name | string | requisNom affiché. 100 max. |
| type | string | requis"income" ou "expense". |
| order | integer | requisPosition de tri au sein de son groupe. |
| isPinned | boolean | requisÉpingle la catégorie en haut du sélecteur. |
| categoryGroupId | string | facultatifId du groupe parent, ou null si la catégorie n’appartient à aucun groupe. |
| icon | string | facultatifIdentifiant d’icône. |
| color | string | facultatifCouleur hexadécimale. |
/api/v1/categories/{id}
categories:write
Remplace une catégorie utilisateur. Le corps est identique à Créer.
/api/v1/categories/{id}
categories:write
Supprime logiquement une catégorie utilisateur. Les transactions ne sont pas supprimées ; leur champ categoryId est simplement vidé.
Groupes de catégories
/api/v1/categories/groups
categories:read
Liste vos groupes de catégories.
/api/v1/categories/groups/{id}
categories:read
Récupère un groupe de catégories.
/api/v1/categories/groups
categories:write
Crée un groupe de catégories.
| Champ | Type | Description |
|---|---|---|
| name | string | requisNom affiché. 100 max. |
| order | integer | requisPosition de tri. |
| icon | string | facultatifIdentifiant d’icône. |
| color | string | facultatifCouleur hexadécimale. |
/api/v1/categories/groups/{id}
categories:write
Remplace un groupe de catégories.
/api/v1/categories/groups/{id}
categories:write
Supprime logiquement un groupe. Les catégories enfants subsistent — leur champ categoryGroupId est vidé.
Budgets
Un budget plafonne les dépenses d’une catégorie (ou, lorsque categoryId vaut null, de l’ensemble du registre) sur une période récurrente. Partagez un budget avec un groupe en renseignant groupId.
/api/v1/budgets
budgets:read
Liste tous les budgets.
/api/v1/budgets/{id}
budgets:read
Récupère un budget.
/api/v1/budgets
budgets:write
Crée un budget.
| Champ | Type | Description |
|---|---|---|
| amount | number | requisPlafond par période. Doit être supérieur à 0. |
| currencyCode | string | requisISO-4217. |
| period | integer | requis0 hebdomadaire · 1 mensuel · 2 trimestriel · 3 annuel. |
| startDate | string (ISO-8601) | requisDébut de la première période. |
| isActive | boolean | requisIndique si ce budget est actuellement appliqué. |
| endDate | string (ISO-8601) | facultatifArrêter le suivi après cette date. |
| name | string | facultatifLibellé. 200 max. |
| categoryId | string | facultatifCatégorie à suivre. Omettre pour budgéter toutes les dépenses. |
| groupId | string | facultatifGroupe avec lequel partager. Omettre pour un budget personnel. |
/api/v1/budgets/{id}
budgets:write
Remplace un budget.
/api/v1/budgets/{id}
budgets:write
Supprime logiquement un budget.
Groupes
Les groupes sont des registres partagés — un foyer, un voyage, une colocation. Chaque membre voit les mêmes transactions ; la propriété, elle, reste personnelle. Les adhésions et les invitations se gèrent dans l’application iOS ; l’API ne couvre ici que la ressource elle-même.
/api/v1/groups
groups:read
Liste les groupes dont vous êtes propriétaire ou membre.
/api/v1/groups/{id}
groups:read
Récupère un groupe.
/api/v1/groups
groups:write
Crée un groupe. Vous en devenez le propriétaire ; invitez les membres depuis l’application iOS.
| Champ | Type | Description |
|---|---|---|
| name | string | requisNom affiché. 100 max. |
| description | string | facultatifTexte libre. 500 max. |
| icon | string | facultatifIdentifiant d’icône. |
| color | string | facultatifCouleur hexadécimale. |
/api/v1/groups/{id}
groups:write
Remplace les métadonnées d’un groupe.
/api/v1/groups/{id}
groups:write
Supprime logiquement un groupe. Les membres perdent la visibilité ; les transactions sous-jacentes redeviennent personnelles.
Transactions
Les transactions sont les verbes du registre. Elles se déclinent en quatre formes : income, expense, transfer (de compte à compte) et adjustment (rééquilibrage ponctuel). L’endpoint de base crée les revenus et les dépenses ; les virements ont leur propre endpoint ; des variantes en lot existent pour les imports à fort volume.
/api/v1/transactions
transactions:read
Liste les transactions avec pagination par curseur et filtres.
| Champ | Type | Description |
|---|---|---|
| limit | integer | facultatifTaille de page. 1..200. Par défaut 50. |
| cursor | string | facultatifJeton de continuation opaque issu de la réponse précédente. |
| type | string | facultatif"income", "expense", "transfer" ou "adjustment". |
| dateFrom | string (ISO-8601) | facultatifBorne inférieure incluse. |
| dateTo | string (ISO-8601) | facultatifBorne supérieure incluse. |
| categoryId | string | facultatifFiltrer sur une seule catégorie. |
| accountId | string | facultatifFiltrer sur un seul compte. |
| groupId | string | facultatifFiltrer sur un groupe partagé. |
{
"items": [ /* TransactionDto[] */ ],
"totalCount": 317,
"nextCursor": "eyJrIjoiMjAyNi0wNS0xM1QxMDoz…"
}
/api/v1/transactions/{id}
transactions:read
Récupère une transaction.
/api/v1/transactions
transactions:write
Crée une seule transaction de revenu ou de dépense. Pour les virements, utilisez /transfer.
| Champ | Type | Description |
|---|---|---|
| type | string | requis"income" ou "expense". |
| amount | number | requisMontant positif exprimé en currencyCode. |
| currencyCode | string | requisISO-4217. |
| date | string (ISO-8601) | requisDate à laquelle la transaction a eu lieu (UTC). |
| accountId | string | facultatifCompte source ou de destination. |
| categoryId | string | facultatifÉtiquette de catégorie. |
| payee | string | facultatifCommerçant ou contrepartie. 200 max. |
| note | string | facultatifNote libre. 2000 max. |
| groupId | string | facultatifPartager avec un groupe. |
| exchangeRate | number | facultatifTaux de change lorsque currencyCode ≠ devise principale de l’utilisateur. |
| convertedAmount | number | facultatifMontant dans la devise principale de l’utilisateur. |
POST /api/v1/transactions
{
"type": "expense",
"amount": 8.50,
"currencyCode": "EUR",
"date": "2026-05-12T09:14:00Z",
"accountId": "acc_01HK8V…",
"categoryId": "cat_food_drinks",
"payee": "Pret",
"note": "Flat white"
}
/api/v1/transactions/{id}
transactions:write
Remplace une transaction. Le corps est identique à Créer.
/api/v1/transactions/{id}
transactions:write
Supprime logiquement une transaction.
/api/v1/transactions/transfer
transactions:write
Crée un virement entre deux comptes. Sans catégorie. Pour les virements multidevises, fournissez exchangeRate et convertedAmount dans la devise de destination.
| Champ | Type | Description |
|---|---|---|
| fromAccountId | string | requisCompte source. |
| toAccountId | string | requisCompte de destination. Doit différer du compte source. |
| amount | number | requisMontant envoyé, exprimé en currencyCode. |
| currencyCode | string | requisDevise source, ISO-4217. |
| date | string (ISO-8601) | requisDate du virement. |
| exchangeRate | number | facultatifObligatoire lorsque les devises source et de destination diffèrent. |
| convertedAmount | number | facultatifMontant crédité sur le compte de destination, dans sa devise. |
| note | string | facultatif2000 max. |
Opérations en lot
Conçues pour les imports. Chaque lot est plafonné à 100 éléments et s’exécute en mode best-effort : une seule ligne invalide n’annule pas les autres. Les éléments traités et les erreurs ligne par ligne sont rapportés séparément, ce qui vous permet de rejouer uniquement les échecs.
/api/v1/transactions/bulk
transactions:write
Crée jusqu’à 100 transactions en un seul appel.
{
"items": [ /* successful TransactionDto[] */ ],
"errors": [
{ "index": 3, "error": "Invalid currency code" }
]
}
/api/v1/transactions/bulk
transactions:write
Met à jour jusqu’à 100 transactions en un seul appel. Chaque élément doit inclure son id en plus du corps complet de la transaction.
/api/v1/transactions/bulk-delete
transactions:write
Supprime logiquement jusqu’à 100 transactions en un seul appel. Utilise POST plutôt que DELETE afin que le corps de requête soit accepté par tous les clients HTTP.
| Champ | Type | Description |
|---|---|---|
| ids | string[] | requisDe 1 à 100 identifiants de transaction. |
{
"deleted": 97,
"notFound": [ "tx_old1", "tx_old2", "tx_old3" ]
}
L’objet transaction
| Champ | Type | Description |
|---|---|---|
| id | string | Identifiant opaque. |
| type | string | income · expense · transfer · adjustment. |
| amount | number | Exprimé en currencyCode. |
| currencyCode | string | ISO-4217. |
| exchangeRate | number | null | Renseigné sur les écritures multidevises. |
| convertedAmount | number | null | La même valeur dans la devise principale de l’utilisateur. |
| date | string | ISO-8601 UTC. |
| accountId | string | null | Pour les virements, il s’agit du compte source. |
| toAccountId | string | null | Compte de destination, sur les virements uniquement. |
| categoryId | string | null | Null sur les virements. |
| groupId | string | null | Renseigné si la transaction est partagée avec un groupe. |
| payee | string | null | Commerçant ou contrepartie. |
| note | string | null | Texte libre. |
| receiptImagePath | string | null | Chemin du reçu joint. À récupérer via l’endpoint des reçus (distinct de v1). |
| recurringTransactionId | string | null | Renseigné si cette ligne a été générée par une règle de récurrence. |
| source | string | Marqueur d’origine — api, mobile, web, import, etc. |
| createdAt | string | ISO-8601 UTC. |
| updatedAt | string | ISO-8601 UTC. |
Icônes
Manilo est livré avec un jeu d’icônes et une palette de couleurs sélectionnés, utilisés partout — comptes, catégories, groupes. Récupérez le catalogue une fois, mettez-le en cache, puis réutilisez les identifiants lors de la création de ressources.
/api/v1/icons
Renvoie la bibliothèque d’icônes complète, regroupée par catégories, ainsi que la palette de couleurs prise en charge. Versionnée — peut être mise en cache sans risque en s’appuyant sur le champ version.
{
"version": "2026.05.10",
"library": "font-awesome-6",
"categories": [
{
"id": "finance",
"name": "Finance",
"icons": [ "wallet", "credit-card", "piggy-bank" ]
}
],
"colors": [
{ "name": "Blue", "hex": "#4A90E2" },
{ "name": "Green", "hex": "#22C55E" }
]
}
Versionnage
- Aucun changement incompatible au sein de v1. Nous n’ajouterons que de nouveaux endpoints, de nouveaux champs facultatifs et de nouvelles valeurs d’énumération. Le type d’un champ, sa nullabilité ou son caractère obligatoire ne changeront pas.
- Les nouvelles valeurs d’énumération ne sont pas incompatibles. Traitez les valeurs inconnues de
type,sourceouactioncomme « à ne pas afficher » plutôt que de faire planter votre client — nous en ajouterons à mesure que le produit s’étoffe. - Les changements incompatibles datés (si jamais ils s’avéraient nécessaires) seront livrés sous
/api/v2/, avec au moins 6 mois de disponibilité en parallèle et un en-tête de dépréciation sur les réponses v1.
Assistance
Vous avez trouvé un bug, vous souhaitez un nouvel endpoint ou vous êtes tombé sur quelque chose de non documenté ? Ouvrez le centre d’aide ou écrivez à support@manilo.app — merci d’indiquer l’identifiant de requête (renvoyé dans l’en-tête de réponse X-Request-Id) lorsque vous signalez un problème.
Pour les divulgations sensibles en matière de sécurité (fuite de jeton, contournement de permission, lecture non autorisée), écrivez à security@manilo.app.