Aller au contenu principal
TarifsEntrepriseSe connecter
Commencez gratuitement

API Era

Découvrez les points de terminaison disponibles, les en-têtes d'authentification, la pagination et les limites de l'API Era.

Dernière mise à jour : 26 août 2026

Encore en bêta

Ces points de terminaison fonctionnent dès aujourd'hui, mais l'API continue d'évoluer, donc certains détails peuvent changer. Consultez la date de dernière mise à jour en haut de page pour savoir quand elle a été révisée pour la dernière fois.

Démarrage rapide

Avant de commencer, il vous faut un compte Era avec au moins un établissement connecté — sans connexion, ces points de terminaison n'ont rien à renvoyer.

  1. 1

    Connectez-vous à Era et reliez un établissement, si ce n'est pas déjà fait.

  2. 2

    Ouvrez vos clés d'API dans le tableau de bord et créez une clé. Toutes les portées sont cochées au départ, donc décochez celles dont vous n'avez pas besoin — pour ces points de terminaison, il ne reste que banking:read. Vous choisissez aussi une expiration ; il n'existe pas d'option « n'expire jamais ».

  3. 3

    Copiez la clé. Elle ne s'affiche qu'une fois, et nous ne pouvons pas la réafficher. Copiez-la et conservez-la en lieu sûr, par exemple dans un gestionnaire de secrets. Si vous perdez une clé, vous ne pouvez plus la consulter. Créez-en une nouvelle à la place.

  4. 4

    Envoyez-la dans un en-tête avec votre requête.

cURL

curl "https://forge.era.app/api/banking/transactions?page=1&pageSize=20" \
  -H "X-API-Key: fmk_your_key_here"

Réponse · 200

{
  "transactions": [],
  "pagination": {
    "currentPage": 1,
    "pageSize": 20,
    "totalItems": 412,
    "totalPages": 21
  },
  "historyWindowApplied": true,
  "historyWindowFloorDate": "2026-06-28",
  "historyWindowHiddenCount": 137,
  "historyWindowEarliestDate": "2024-03-02",
  "historyWindowDegraded": false
}

Authentification

Envoyez votre clé de l'une de ces deux façons :

Méthodes d'authentification
MéthodeIdentifiant
En-têteX-API-Key: fmk_your_key_here
Jeton bearerAuthorization: Bearer fmk_your_key_here

Chaque requête est chiffrée avec TLS.

Les clés expirent, et vous choisissez au bout de combien de temps au moment de les créer. Le maximum est de 90 jours sur le forfait gratuit et de 365 sur un forfait payant — il n'existe pas d'option « n'expire jamais », donc tout ce que vous construisez là-dessus doit prévoir la rotation de la clé avant qu'elle n'expire.

En-têtes de réponse

Chaque réponse inclut :

En-têtes de réponse
En-têteDescription
fly-request-id

Un identifiant unique pour la requête. Indiquez-le lorsque vous contactez le support à propos d'une requête précise — voir ID de requête

Erreurs

L'API renvoie ces codes de statut d'erreur :

  • 400

    Entrée invalide : un paramètre incorrect, une mise à jour groupée vide ou de plus de 100 éléments, ou une écriture qui définit et efface le même champ dans le même appel.

  • 401

    Pas de clé, ou une clé qui ne s'analyse pas. Envoyez-la dans l'en-tête X-API-Key ou comme jeton bearer.

  • 402

    Un quota du forfait fait obstacle — aujourd'hui, cela ne concerne que la création de catégories.

  • 403

    La clé ne porte pas la portée dont cet appel a besoin — ou, sur l'une des deux écritures de transactions, l'id appartient à quelqu'un d'autre ou n'existe pas. L'API ne distingue pas ces deux cas.

  • 409

    Autre chose a modifié la ligne pendant que vous écriviez. Relisez-la et renvoyez votre écriture.

Formes d'erreur

Chaque erreur revient sous la même forme : statusCode, message et un objet errors qui nomme ce qui n'allait pas. Une clé absente ou invalide peut revenir sans corps du tout.

Exemple

{
  "statusCode": 403,
  "message": "One or more errors occurred!",
  "errors": {
    "generalErrors": ["Transaction does not belong to the authenticated user"]
  }
}

ID de requête

Chaque réponse porte un en-tête fly-request-id. Indiquez-le lorsque vous contactez le support à propos d'une requête précise.

cURL

# Print the response headers, including fly-request-id; discard the body
curl -sS -D - -o /dev/null "https://forge.era.app/api/banking/transactions?page=1&pageSize=20" \
  -H "X-API-Key: fmk_your_key_here"

cURL (écriture)

# A write call: same header, plus a JSON body
curl -sS -D - -X PUT "https://forge.era.app/api/banking/transactions/utgr_your_transaction_id" \
  -H "X-API-Key: fmk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"categoryKey": "fcat_dining", "merchantName": "Corner Cafe"}'

Erreurs courantes

  • Définir un champ et l'effacer dans la même écriture — 400.

  • Plus de 100 id dans une mise à jour groupée — 400, et rien n'est modifié. Moins d'un id donne le même résultat.

  • Une transaction qui n'est pas la vôtre, ou qui n'existe pas — 403, jamais 404. La réponse ne vous dit donc jamais si un id existe, seulement qu'il n'est pas à vous.

  • Autre chose a modifié la ligne en premier — 409.

Limites

Deux des dix endpoints documentés plafonnent ce que vous pouvez demander en un seul appel. Les huit autres non.

Cela ne veut pas dire illimité : les clés expirent toujours, les écritures ont toujours des limites de longueur de champ, et votre forfait peut toujours masquer l'historique ancien. Rien de tout cela n'est une limite de débit — voir ci-dessous.

  • Comptes, solde, résumé, catégories, tags et l'écriture d'une seule transaction n'ont aucun plafond de volume par appel. Vous recevez l'ensemble complet, ou la seule ligne que vous avez nommée.

  • pageSize est plafonné à 100, jamais refusé. Demandez-en plus et vous recevez 100 lignes avec un 200 — lisez pagination.pageSize dans la réponse plutôt que de faire confiance à ce que vous avez envoyé.

  • L'écriture groupée de transactions est plafonnée à 100 id, et contrairement à pageSize elle est refusée plutôt que plafonnée : envoyez 101 et vous recevez un 400, rien ne change.

  • Les clés expirent selon un calendrier que vous choisissez à la création — jusqu'à 90 jours sur le forfait gratuit, 365 sur un forfait payant. Il n'existe pas d'option sans expiration.

  • Votre forfait peut appliquer un plancher de fenêtre d'historique qui masque les transactions plus anciennes. La réponse des transactions porte les champs historyWindow qui indiquent si un plancher s'est appliqué et où il se situe.

  • Les forfaits indiquent aussi une allocation de requêtes API — 500 sur le forfait gratuit, plus sur chaque forfait payant.

Ce qui n'existe pas : aucune limitation par requête sur REST aujourd'hui, pas de 429, pas d'en-têtes de limite de débit — une clé qui a fuité n'est donc ralentie par rien de notre côté. Si vous avez un doute sur une clé, révoquez-la : cela la coupe immédiatement (voir Sécurité et gestion des clés plus haut). Et, cette API étant en bêta, ne présumez pas que cela restera vrai.

Conventions

Les champs de réponse sont en camelCase. Les paramètres de requête, eux, ne sont pas sensibles à la casse, donc le camelCase fonctionne là aussi — la spécification publiée les écrit en PascalCase, et c'est pour cela que vous verrez les deux formes circuler.

Un champ qui désigne un jour de calendrier est en YYYY-MM-DD. Un champ qui désigne un instant précis est en ISO 8601 avec un décalage horaire.

Les tailles de page sont ramenées dans les bornes, pas refusées. Demandez un pageSize de 500 et vous obtenez 100 lignes et un 200, pas une erreur — donc relisez pagination.pageSize dans la réponse plutôt que de vous fier à ce que vous avez envoyé.

Une réponse peut porter des champs que cette page ne liste pas. Ignorez ceux que vous ne reconnaissez pas plutôt que d'échouer dessus — c'est ce qui garde votre client fonctionnel à mesure que l'API s'étoffe.

REST, c'est du HTTP ordinaire, donc aucun SDK n'est nécessaire pour l'appeler — n'importe quel langage doté d'un client HTTP fait l'affaire. Il n'y a rien à installer.

Sécurité et gestion des clés

Approuver un agent crée une clé

Quand vous approuvez un agent en OAuth, Era lui crée une clé d'API. Elle arrive dans la même liste du tableau de bord que celles que vous créez vous-même, sous un nom qu'Era compose à partir du nom du client.

Comment elle est nommée

Auto -- Claude

Elle porte exactement les portées que vous avez approuvées sur cet écran, et rien d'autre. Révoquez-la depuis le tableau de bord et l'agent cesse d'atteindre votre compte jusqu'à ce que vous l'approuviez à nouveau.

Les simples appels REST ne sont pas journalisés

La création et la révocation d'une clé apparaissent toutes les deux dans votre journal d'activité, tout comme chaque appel d'outil qu'un agent fait en MCP. Les appels REST individuels, non — lectures comme écritures — il n'y a pas de journal requête par requête sur ce chemin aujourd'hui.

Si vous avez le moindre doute sur une clé, révoquez-la. La révocation est immédiate, coupe la clé aussi bien en REST qu'en MCP, et en refaire une prend une minute.

D'autres choses à savoir avant de vous fier à une clé.
FaitCe que ça signifie
Les portées sont larges

banking:read couvre bien plus que les six lectures de cette page — la même portée couvre aussi le reste des lectures de votre compte : soldes, positions, connexions, dépenses. Une seule portée, il n'existe pas plus étroit. Les portées d'écriture sont au menu elles aussi, comme celles de lecture — alors traitez n'importe quelle clé comme un mot de passe. Elle agit au nom de votre compte, pas d'une partie de celui-ci. banking:write peut modifier des catégories, des étiquettes et les métadonnées d'une transaction, gérer des comptes et des soldes manuels, et connecter ou déconnecter des institutions — aucune portée de cette page ne peut déplacer de l'argent entre vos comptes bancaires.

Les portées ne se mettent pas à jour

Les portées d'une clé sont fixées à sa création et ne changent jamais ensuite. C'est important pour tout ce qu'une portée couvre et qui n'est pas encore activé : accordez social:write aujourd'hui et la clé l'aura encore le jour où les vues partagées arriveront. Accordez ce que vous utilisez maintenant, pas ce que vous utiliserez peut-être.

Aucune approbation requise

Vous êtes déjà connecté à votre propre compte, donc créer une clé ne nécessite l'accord de personne d'autre — il n'y a ni examen ni liste d'attente, et personne chez Era n'approuve la demande. C'est inscrit dans votre journal d'activité dès sa création, donc une clé que vous ne reconnaissez pas est facile à repérer.

Les identifiants bancaires restent hors de portée

Une clé n'atteint pas vos identifiants bancaires, parce qu'Era ne les a jamais. Vous les saisissez dans le parcours de connexion géré par le fournisseur de données, pas sur un écran d'Era — ce qu'Era conserve ensuite, c'est un jeton d'accès par connexion, chiffré au repos avec AES-256, dont vous pouvez vous débarrasser en déconnectant l'établissement.

Les clés sont hachées, pas stockées

Votre clé, c'est 256 bits de données aléatoires, hachés en SHA-256 avant d'être stockés. Nous gardons le haché, pas la clé. Si vous la perdez, révoquez-la et créez-en une autre.

Ressources principales

Comptes

GET/banking/accounts

Portée requise

banking:read

Tous les comptes que vous pouvez voir, dans chaque établissement connecté, avec à côté le nombre de ceux qui sont laissés de côté. Chaque compte porte son accountGroupKey — la valeur que le point de terminaison de solde prend dans son chemin — et le connectionId auquel il appartient, c'est donc le premier appel à faire. Accepte connectionId pour se limiter à une seule connexion, et includeExcluded pour ramener les comptes que vous avez masqués.

Paramètres de requête
connectionIdfacultatif

Limite la liste aux comptes d'une seule connexion.

includeExcludedfacultatif

Inclut aussi les comptes exclus par palier et les comptes masqués, avec leurs soldes brouillés. Par défaut, false.

Réponse · 200

{
  "accounts": [
    {
      "accountGroupKey": "uagr_7f3c9a21",
      "connectionId": "ucon_4b19e02c",
      "name": "Everyday Checking",
      "currentBalance": 4820.16,
      "supportsTransactions": true,

    }
  ],
  "excludedAccountCount": 1
}

Sur un compte que vous avez masqué ou que votre forfait exclut, les champs de solde reviennent à null plutôt qu'à zéro — null veut dire retenu, pas vide. supportsTransactions vaut null dans le même esprit. Cela veut dire qu'Era ne peut pas se prononcer, jamais que la réponse est non.

Solde d'un compte

GET/banking/accounts/{accountId}/balance

Portée requise

banking:read

Le solde d'un seul compte, avec les champs de crédit remplis quand le compte est un passif. Le chemin prend l'accountGroupKey de ce compte — la même valeur que /banking/accounts retourne pour lui. Une clé d'une autre forme est rejetée avant même que la recherche s'exécute.

Réponse · 200

{
  "accountGroupKey": "uagr_7f3c9a21",
  "currentBalance": 4820.16,
  "availableBalance": 4712.03,
  "creditLimit": null,
  "currencyCode": "USD",
  "availableCredit": null,
  "asOf": "2026-08-11T09:32:00Z",
  "visibility": null
}

Un compte masqué, ou un compte dont la connexion a été coupée, répond quand même 200 — avec les champs de solde à null. Seul un compte qui n'existe vraiment pas vous donne un 404. Surveillez le champ visibility ici — il vaut null quand le compte est visible, et une chaîne comme tier_excluded quand il ne l'est pas.

Synthèse des comptes

GET/banking/accounts/summary

Portée requise

banking:read

Les totaux sur les comptes que vous pouvez voir — totalAssets, totalLiabilities et netWorthHint, qui est le premier moins le second. N'accepte aucun paramètre.

Réponse · 200

{
  "userId": "7d1c0b93a8e24f60",
  "accounts": [],
  "totalVisibleCount": 6,
  "totalHiddenCount": 2,
  "totalAssets": 48210.75,
  "totalLiabilities": 9327.40,
  "netWorthHint": 38883.35,
  "computedAt": "2026-08-11T09:32:00Z"
}

netWorthHint ne compte que les comptes présents dans cette réponse, donc totalHiddenCount vous dit ce qui lui manque. Prenez-le comme un chiffre de départ plutôt que comme une valeur nette faisant autorité.

Transactions

GET/banking/transactions

Portée requise

banking:read

Vos transactions, une page à la fois, dans une enveloppe qui porte les compteurs de pagination à côté. Accepte page et pageSize (100 au maximum), plus des filtres facultatifs par compte, plage de dates, règles appliquées et étiquettes assignées.

Paramètres de requête
accountIdfacultatif

Limite aux transactions d'un compte, par son accountGroupKey.

fromDatefacultatif

Seulement les transactions à cette date ou après.

toDatefacultatif

Seulement les transactions à cette date ou avant.

pagefacultatif

Numéro de page, à partir de 1. Par défaut, 1.

pageSizefacultatif

Lignes par page. Par défaut, 50, plafonné à 100.

sortByfacultatif

Champ de tri : transactionDate, amount, description, category ou merchantName.

sortDirectionfacultatif

asc ou desc. Par défaut, décroissant.

categoryKeyfacultatif

Seulement les transactions d'une catégorie, par sa clé fcat_.

searchfacultatif

Recherche plein texte sur le commerçant, la description, la catégorie, le nom du compte et le montant.

ruleIdsfacultatif

Seulement les transactions qu'une règle d'automatisation a touchées, par la clé de la règle.

tagKeysfacultatif

Seulement les transactions qui portent l'une de ces étiquettes.

reviewStatusfacultatif

needs_review, reviewed ou flagged.

includeChildrenfacultatif

Avec categoryKey défini, inclut aussi ses sous-catégories. Par défaut, false.

Réponse · 200

{
  "transactions": [],
  "pagination": {
    "currentPage": 1,
    "pageSize": 20,
    "totalItems": 412,
    "totalPages": 21
  },
  "historyWindowApplied": true,
  "historyWindowFloorDate": "2026-06-28",
  "historyWindowHiddenCount": 137,
  "historyWindowEarliestDate": "2024-03-02",
  "historyWindowDegraded": false
}

Votre forfait peut appliquer un plancher de fenêtre d'historique, qui masque les transactions plus anciennes que lui. C'est pour cela que la réponse porte les champs historyWindow : historyWindowApplied vous dit qu'un plancher a bel et bien masqué quelque chose, historyWindowFloorDate indique où il tombe, historyWindowHiddenCount combien de lignes se trouvent derrière, et historyWindowEarliestDate jusqu'où votre historique remonte vraiment. Sans eux, un résultat court est impossible à distinguer d'un compte sans transactions plus anciennes. Deux d'entre eux changent ce que vous écrivez : historyWindowHiddenCount peut valoir null même quand un plancher s'est appliqué, alors lisez null comme une valeur inconnue plutôt que comme un zéro. Et quand historyWindowDegraded vaut true, Era n'a pas pu confirmer votre forfait sur cette lecture, donc la date du plancher est une supposition et non un fait. Sur une lecture payante confirmée, aucun plancher ne s'applique et historyWindowApplied revient à false.

Les forfaits indiquent aussi un quota de requêtes d'API — 500 sur le forfait gratuit, davantage sur chaque forfait payant. Les chiffres actuels sont listés avec le reste des limites de votre forfait.

Modifier une transaction

Quatre éléments d'une transaction peuvent être remplacés par les vôtres : sa catégorie, le nom du commerçant, une note personnelle et son statut de révision. N'envoyez que ceux que vous modifiez — tout ce que vous omettez reste tel quel. L'id dans le chemin est la clé utgr_ de la transaction. Cela modifie des données, il faut donc banking:write plutôt que banking:read.

PUT/banking/transactions/{id}

Portée requise

banking:write
Corps de la requête
categoryKeyfacultatif

La clé fcat_ de la catégorie à assigner. Omettez-la et la transaction garde la catégorie qu'elle a.

merchantNamefacultatif

Un nom de commerçant à vous, jusqu'à 1000 caractères. Omettez-le et le nom actuel reste inchangé.

descriptionfacultatif

Une note personnelle sur cette transaction, jusqu'à 5000 caractères. Omettez-la et la note actuelle reste inchangée.

reviewStatusfacultatif

Marquez-la needs_review, reviewed ou flagged.

clearCategoryfacultatif

Supprime votre substitution de catégorie, pour que la catégorisation propre à Era reprenne la main. Par défaut, false.

clearMerchantNamefacultatif

Supprime votre substitution de nom de commerçant, pour que le nom envoyé par votre banque revienne. Par défaut, false.

clearDescriptionfacultatif

Supprime votre substitution de description, pour que la description envoyée par votre banque revienne. Par défaut, false.

clearReviewStatusfacultatif

Supprime votre substitution de statut de révision. Par défaut, false.

Réponse · 200

{
  "transaction": {}
}

Vous récupérez la transaction mise à jour en entier, dans la même forme que la liste ci-dessus — non reproduite ici, parce que c'est un objet volumineux encore en mouvement. Définir un champ et le réinitialiser dans le même appel renvoie 400. Une transaction qui n'est pas la vôtre, ou qui n'existe pas du tout, renvoie 403 — l'API ne fait pas la différence entre les deux. Et si autre chose a modifié la même ligne pendant que vous écriviez, vous obtenez 409 : relisez-la et renvoyez-la.

Modifier jusqu'à 100 à la fois

Les quatre mêmes substitutions, appliquées à une liste de transactions en un seul appel. Chaque id de la liste reçoit les mêmes changements — il n'y a pas de variation par transaction. Cela modifie des données, il faut donc banking:write plutôt que banking:read.

PUT/banking/transactions/bulk

Portée requise

banking:write
Corps de la requête
transactionIds

Les clés utgr_ des transactions à modifier. Au moins une, et pas plus de 100. Au-delà de 100, la requête est refusée plutôt que tronquée — contrairement à pageSize plus haut, vous obtenez un 400 et rien n'est modifié.

categoryKeyfacultatif

La clé fcat_ de la catégorie à assigner. Omettez-la et la transaction garde la catégorie qu'elle a.

merchantNamefacultatif

Un nom de commerçant à vous, jusqu'à 1000 caractères. Omettez-le et le nom actuel reste inchangé.

descriptionfacultatif

Une note personnelle sur cette transaction, jusqu'à 5000 caractères. Omettez-la et la note actuelle reste inchangée.

reviewStatusfacultatif

Marquez-la needs_review, reviewed ou flagged.

clearCategoryfacultatif

Supprime votre substitution de catégorie, pour que la catégorisation propre à Era reprenne la main. Par défaut, false.

clearMerchantNamefacultatif

Supprime votre substitution de nom de commerçant, pour que le nom envoyé par votre banque revienne. Par défaut, false.

clearDescriptionfacultatif

Supprime votre substitution de description, pour que la description envoyée par votre banque revienne. Par défaut, false.

clearReviewStatusfacultatif

Supprime votre substitution de statut de révision. Par défaut, false.

Réponse · 200

{
  "transactions": []
}

Vous récupérez les transactions mises à jour, dans la même forme que la liste ci-dessus. Définir un champ et le réinitialiser dans le même appel renvoie 400, tout comme une liste vide. Une liste contenant une transaction qui n'est pas la vôtre, ou qui n'existe pas du tout, renvoie 403 pour l'appel entier — rien n'est modifié. Si autre chose a modifié l'une de ces lignes pendant que vous écriviez, vous obtenez 409 : relisez-les et renvoyez-les.

Catégories

GET/banking/categories

Portée requise

banking:read

Toute la taxonomie des catégories : chaque ensemble de catégories, avec ses sous-catégories imbriquées dedans. La taxonomie est partagée, pas propre à un compte.

Réponse · 200

{
  "packs": [
    {
      "packSlug": "default",
      "packName": "Era default categories",
      "isDefault": true,
      "categories": [
        {
          "projectionKey": "fcat_food_dining",
          "categoryName": "Food & dining",
          "isTopLevel": true,
          "children": []
        }
      ]
    }
  ],
  "meterLimit": 25,
  "canCreateCustomCategories": true
}

Ajouter une catégorie

Une catégorie définie par l'utilisateur, sous un parent existant. Cela modifie des données, il faut donc banking:write plutôt que banking:read.

POST

Portée requise

banking:write
Corps de la requête
slug

Identifiant compatible URL — lettres minuscules, chiffres et traits d'union, de 2 à 50 caractères.

parentCategoryKey

La clé fcat_ de la catégorie sous laquelle celle-ci s'imbrique.

name

Nom affiché.

descriptionfacultatif

Description facultative.

iconNamefacultatif

Nom d'icône facultatif.

spendingTypefacultatif

Classification de dépense facultative.

displayOrderfacultatif

Position de tri facultative parmi ses catégories sœurs.

assignmentEligibilityfacultatif

Règle facultative sur les transactions auxquelles cette catégorie peut être assignée.

sourceSystemKeysfacultatif

Liste facultative de clés de catégories existantes dont les transactions doivent être redirigées ici à partir de maintenant.

applyRetroactivelyfacultatif

Si true, réévalue aussi les transactions passées selon le nouvel acheminement. Par défaut, false.

Réponse · 201

{
  "categoryKey": "fcat_side_hustle_9f2a",
  "overlayProjectionKey": "fcov_9f2a1c",
  "action": "created",
  "isQuotaExceeded": false,
  "createdMappingRuleKeys": [],

}

La réponse porte aussi retroactiveAffectedCount, mergeSourcesHiddenCount, mergeSourcesTotalCount et meterGate — des champs que cet appel partage avec les fusions de catégories et les créations limitées par quota, non montrés ici.

Étiquettes

GET/banking/tags

Portée requise

banking:read

Toutes les étiquettes de votre compte, en une seule liste. Pas de pagination — une seule réponse les renvoie toutes.

Paramètres de requête
tagTypefacultatif

Filtre par origine de l'étiquette : user, system ou auto.

includeDeletedfacultatif

Inclut les étiquettes supprimées. Par défaut, false.

Réponse · 200

{
  "tags": [
    {
      "tagKey": "utag_9c2f01ab",
      "name": "business-expense",
      "displayName": "Business expense",
      "tagType": "user",
      "color": "#6DC6BA",
      "transactionCount": 42
    }
  ]
}

Créer une étiquette

Une nouvelle étiquette, normalisée en minuscules. Cela modifie des données, il faut donc banking:write plutôt que banking:read — et cela ne peut créer que des étiquettes user; system n'est pas autorisé par l'API.

POST

Portée requise

banking:write
Corps de la requête
name

Le nom canonique de l'étiquette.

displayNamefacultatif

Nom affiché facultatif. Par défaut, le nom canonique.

tagTypefacultatif

Par défaut, user — la seule valeur que l'API accepte ici.

colorfacultatif

Couleur hexadécimale facultative pour l'affichage.

iconfacultatif

Nom d'icône facultatif.

Réponse · 201

{
  "tag": {
    "tagKey": "utag_9c2f01ab",
    "name": "business-expense",
    "displayName": "Business expense",
    "tagType": "user",
    "version": 1,
    "createdAt": "2026-08-26T09:15:00Z"
  }
}