Era-API
Erfahre mehr über die verfügbaren Endpunkte, Authentifizierungs-Header, Paginierung und Limits der Era-API.
Zuletzt aktualisiert: 29. September 2026
Diese Endpunkte funktionieren schon heute, aber die API entwickelt sich noch weiter, deshalb können sich einzelne Details noch ändern. Das Datum der letzten Aktualisierung oben zeigt dir, wann diese Seite zuletzt überarbeitet wurde.
Schnellstart
Bevor du loslegst, brauchst du ein Era-Konto mit mindestens einer verbundenen Bank — ohne Verbindung haben diese Endpunkte nichts zurückzugeben.
- 1
Melde dich bei Era an und verbinde eine Bank, falls noch nicht geschehen.
- 2
Öffne deine API-Schlüssel im Dashboard und erstell einen. Alle Scopes sind vorab angehakt, also hak die ab, die du nicht brauchst — für diese Endpunkte bleibt banking:read übrig. Du wählst außerdem eine Gültigkeitsdauer; eine Option „läuft nie ab“ gibt es nicht.
- 3
Kopier den Schlüssel. Er wird einmal angezeigt, und wir können ihn nicht erneut zeigen. Kopier ihn und bewahr ihn an einem sicheren Ort auf, zum Beispiel in einem Secrets-Manager. Verlierst du einen Schlüssel, kannst du ihn nicht erneut einsehen. Leg stattdessen einen neuen an.
- 4
Schick ihn mit deinem Request im Header mit.
curl "https://forge.era.app/api/banking/transactions?page=1&pageSize=20" \
-H "X-API-Key: fmk_your_key_here"{
"transactions": [ … ],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 412,
"totalPages": 21
},
"historyWindowApplied": true,
"historyWindowFloorDate": "2026-06-28",
"historyWindowHiddenCount": 137,
"historyWindowEarliestDate": "2024-03-02",
"historyWindowDegraded": false
}Verfügbare APIs
Die Era-API umfasst die folgenden APIs:
- GET
- GET/banking
/accounts /{accountId} /balanceDer Saldo eines Kontos, inklusive Kreditfelder bei einer Verbindlichkeit. - GET/banking
/accounts /summarySummen über alle Konten, die du sehen kannst. - GET/banking
/transactionsDeine Transaktionen, seitenweise. - PUT/banking
/transactions /{id}Eine Transaktion ändern - PUT/banking
/transactions /bulkBis zu 100 auf einmal ändern - GET/banking
/categoriesDie gesamte Kategorie-Taxonomie, mit verschachtelten Unterkategorien. - POST/banking
/categoriesEine Kategorie anlegen - GET/banking
/tagsAlle Tags deines Kontos, in einer Antwort. - POST/banking
/tagsEinen Tag anlegen
Authentifizierung
Sende deinen Schlüssel auf eine von zwei Arten:
- Header
- X-API-Key: fmk_your_key_here
- Bearer-Token
- Authorization: Bearer fmk_your_key_here
Jeder Request ist TLS-verschlüsselt.
Schlüssel laufen ab, und du wählst beim Erstellen, wie bald. Das Maximum sind 90 Tage im kostenlosen Tarif und 365 in einem bezahlten — eine Option „läuft nie ab“ existiert nicht, also braucht alles, was du darauf baust, einen Plan zum Rotieren des Schlüssels, bevor er verfällt.
Antwort-Header
Eine Request-ID kommt bei jeder Antwort zurück. Die Rate-Limit-Header kommen bei den Aufrufen zurück, die Era gegen ein Tagesbudget gemessen hat. Bei einem 429 kommen sie nur, wenn dieses Tagesbudget den Aufruf abgelehnt hat: Ein 429 von der Minuten-Burst-Grenze trägt nur Retry-After. Vorerst hat nur der kostenlose Tarif ein Tagesbudget. Wenn Era deine Nutzung nicht messen kann, wird der Aufruf bedient und es geht keiner von ihnen raus.
- fly-request-id
- Eine eindeutige Kennung für die Anfrage. Gib sie an, wenn du den Support zu einer bestimmten Anfrage kontaktierst — siehe Request-ID
- X-RateLimit-Limit
- Das Tagesbudget deines Tarifs. Wird nur in Tarifen mit Tagesbudget gesendet und nie bei einem 429 von der Minuten-Burst-Grenze.
- X-RateLimit-Remaining
- Was von deinem Tagesbudget übrig ist. Nie unter null. Wird nur in Tarifen mit Tagesbudget gesendet und nie bei einem 429 von der Minuten-Burst-Grenze.
- X-RateLimit-Reset
- Wann dein Tagesbudget als Nächstes eine Anfrage freigibt, als Unix-Zeitstempel in Sekunden. Das ist nicht der Zeitpunkt, an dem das ganze Budget wieder voll ist: Das Budget rollt, Anfragen kommen also einzeln zurück. Wird nur in Tarifen mit Tagesbudget gesendet und nie bei einem 429 von der Minuten-Burst-Grenze. Die Minuten-Burst-Grenze hat keinen eigenen Header. Siehe Limits
- Retry-Afternur bei 429
- Wie viele Sekunden du vor einem neuen Versuch warten sollst, gemessen an der Grenze, die die Anfrage abgelehnt hat. Trägt ein 429 zusätzlich X-RateLimit-*, hat das Tagesbudget abgelehnt; fehlen sie, die Minuten-Burst-Grenze. Siehe Limits
Fehler
Die API liefert diese Fehler-Statuscodes:
- 400
Fehlerhafte Eingabe: ein falscher Parameter, ein leeres oder über 100 Einträge großes Bulk-Update, oder ein Schreibzugriff, der dasselbe Feld im selben Aufruf setzt und löscht.
- 401
Kein Schlüssel, oder einer, der sich nicht parsen lässt. Sende ihn als X-API-Key-Header oder als Bearer-Token.
- 402
Ein Tarifkontingent steht im Weg — heute betrifft das nur das Anlegen von Kategorien. Es geht darum, was du anlegst, nicht wie schnell du aufrufst: Warten löst es nicht, ein größerer Tarif schon. Zu schnelles Aufrufen ist dagegen ein 429.
- 403
Der Schlüssel trägt nicht den Scope, den dieser Aufruf braucht — oder, bei einem der beiden Transaktions-Schreibzugriffe, die ID gehört jemand anderem oder existiert gar nicht. Die API unterscheidet die beiden Fälle nicht.
- 404
Ein Konto, das es nicht gibt. Nur der Kontostand-Endpunkt gibt das zurück: ein accountGroupKey, der kein Konto benennt, oder einer, der gar nicht wie ein Schlüssel aussieht, kommt als 404 ohne Body zurück. Transaktionen liefern nie 404 — siehe 403.
- 409
Etwas anderes hat die Zeile geändert, während du geschrieben hast. Lies sie erneut und schreibe erneut.
- 429
Zu viele Anfragen. Du hast die Minuten-Burst-Grenze erreicht oder, im kostenlosen Tarif, dein Tagesbudget aufgebraucht. Ein 429 mit den X-RateLimit-*-Headern ist das Tagesbudget, einer ohne sie die Burst-Grenze. Retry-After sagt, wie lange du warten musst, und anders als bei einem 402 macht Warten deine nächste Anfrage frei. Unter Limits stehen die Zahlen pro Tarif.
Fehlerformen
Die meisten Fehler kommen in derselben Form zurück — statusCode, message und ein errors-Objekt, das benennt, was falsch war. Nicht alle: Ein 401 und ein 404 kommen ganz ohne Body zurück, lies also den Status, bevor du den Body liest.
{
"statusCode": 403,
"message": "One or more errors occurred!",
"errors": {
"generalErrors": ["Transaction does not belong to the authenticated user"]
}
}Request-ID
Jede Antwort trägt einen fly-request-id-Header. Gib ihn an, wenn du den Support zu einer bestimmten Anfrage kontaktierst.
# 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"# 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"}'Häufige Fehler
Ein Feld im selben Schreibzugriff setzen und löschen — 400.
Mehr als 100 IDs in einem Bulk-Update — 400, und nichts wird geändert. Weniger als eine ID ist genauso.
Eine Transaktion, die nicht dir gehört oder gar nicht existiert — 403, niemals 404. Die Antwort verrät also nie, ob eine ID überhaupt existiert, nur dass sie nicht dir gehört.
Etwas anderes hat die Zeile zuerst geändert — 409.
Limits
Zwei der zehn dokumentierten Endpunkte begrenzen, wie viel du in einem Aufruf anfordern kannst. Die anderen acht nicht.
Keine Obergrenze pro Aufruf heißt nicht unbegrenzt. Schlüssel laufen weiterhin ab, Schreibvorgänge haben weiterhin Feldlängenbegrenzungen, das Anlegen einer Kategorie kann an ein Tarifkontingent stoßen, dein Tarif kann weiterhin älteren Verlauf ausblenden, und jeder Aufruf zählt gegen die Rate-Limits deines Tarifs, die unten beschrieben sind.
Konten, Kontostand, Übersicht, die Kategorie- und Tag-Listen, das Anlegen einer Kategorie, das Anlegen eines Tags und das Schreiben einzelner Transaktionen haben kein Volumenlimit pro Aufruf. Du bekommst entweder die gesamte Menge zurück oder genau die eine Zeile, die du benannt hast.
pageSize wird auf 100 gekappt, nicht abgelehnt. Fordere mehr an, und du bekommst 100 Zeilen mit einem 200 zurück — lies pagination.pageSize aus der Antwort, statt dem zu vertrauen, was du gesendet hast.
Der Bulk-Schreibzugriff für Transaktionen ist auf 100 IDs gedeckelt, und anders als pageSize wird er abgelehnt statt gekappt: Sende 101, und du bekommst einen 400, und nichts ändert sich.
Schlüssel laufen nach einem Zeitplan ab, den du bei der Erstellung wählst — bis zu 90 Tage im kostenlosen Tarif, 365 in einem bezahlten. Es gibt keine Option, die nie abläuft.
Dein Tarif kann eine Verlaufsfenster-Untergrenze setzen, die ältere Transaktionen verbirgt. Die Transaktions-Antwort trägt die historyWindow-Felder, die dir sagen, ob eine galt und wo sie lag.
Rate-Limits
Die API setzt zwei Rate-Limits durch. Jeder Tarif hat eine Burst-Grenze: eine Obergrenze für Anfragen innerhalb jeder gleitenden Minute. Der kostenlose Tarif hat zusätzlich ein Tagesbudget: eine Obergrenze für Anfragen innerhalb von jeweils 24 gleitenden Stunden. Eine Anfrage zählt eine Minute, nachdem du sie gestellt hast, nicht mehr gegen die Burst-Grenze und einen Tag danach nicht mehr gegen das Tagesbudget. Bezahlte Tarife haben vorerst kein Tagesbudget, in einem bezahlten Tarif ist die Burst-Grenze also die einzige Grenze. Überschreitest du eine der beiden, kommt der Aufruf mit 429 zurück.
Grenzen gehören zu deinem Konto, nicht zu einem Schlüssel. Jeder REST-Schlüssel, den du anlegst, zählt gegen dieselbe Burst-Grenze und, im kostenlosen Tarif, gegen dasselbe Tagesbudget. Ein zweiter Schlüssel bringt dir also keine zusätzlichen Aufrufe. MCP-Tool-Aufrufe werden getrennt gezählt, REST- und MCP-Aufrufe verbrauchen also nie die Grenzen des jeweils anderen.
| Tarif | Tagesbudget | Burst-Grenze |
|---|---|---|
| Basic | 100 pro Tag | 10 pro Minute |
| Organize | Keins | 30 pro Minute |
| Automate | Keins | 60 pro Minute |
| Optimize | Keins | 60 pro Minute |
| Operate | Keins | 120 pro Minute |
Vorerst haben bezahlte Tarife kein Tagesbudget.
Bezahlte Tarife gelten außerdem im Rahmen der fairen Nutzung. Das ist eine Richtlinie, kein Zähler, die API lehnt deswegen also nie einen Aufruf ab. Die API ist für Skripte, Dashboards und Integrationen mit deinen eigenen Finanzdaten gedacht, in einem Umfang, der zu einer Person passt. Wenn wir den Eindruck haben, dass deine Nutzung darüber hinausgeht, sperren wir dein Konto nicht, ohne dich vorher zu kontaktieren. Auf der Preisseite heißt das „Vorerst unbegrenzt (faire Nutzung)“.
Im kostenlosen Tarif meldet jede bediente Antwort dein Tagesbudget in den X-RateLimit-*-Headern, die unter Antwort-Header beschrieben sind. Die Antworten eines bezahlten Tarifs enthalten keinen davon. Kein Header meldet die Burst-Grenze, in keinem Tarif. Richte dein Tempo also nach der Tabelle: Im kostenlosen Tarif kann Remaining deutlich über null stehen, kurz bevor ein Burst mit 429 zurückkommt. Kann Era deine Nutzung nicht messen, bedient es den Aufruf ohne die Header. Lies eine Antwort im kostenlosen Tarif ohne Header also als unbekannten Stand, nicht als Fehler.
Was ein 429 dir sagt
Welche Grenze dich abgewiesen hat. Ein 429 mit den X-RateLimit-*-Headern kam vom Tagesbudget, einer ohne sie von der Burst-Grenze. Das gilt in jedem Tarif. Der Body ist im Problem-Details-Format, und sein detail-Feld nennt die Grenze, was sie erlaubt, wann deine nächste Anfrage frei wird und den Tarif, der sie anhebt oder aufhebt, oder dass du schon im höchsten bist. Es ist für Menschen geschrieben, lies also die Header, statt es zu parsen.
{
"type": "https://httpstatuses.com/429",
"title": "Too Many Requests",
"status": 429,
"detail": "You've used up your daily budget of 100 requests. Your next request frees up at 2026-09-16T09:00:00Z. The Organize plan removes it."
}Jeder 429 enthält außerdem Retry-After: eine ganze Zahl von Sekunden, nie weniger als eine. Bei der Burst-Grenze ist es bis zu eine Minute, beim Tagesbudget des kostenlosen Tarifs bis zu 24 Stunden. Ein abgewiesener Aufruf zählt gegen keine der beiden Grenzen, aber ein erneuter Versuch vor Ablauf von Retry-After wird wieder abgewiesen. Warte also ab. Danach wird eine Anfrage frei, nicht die ganze Grenze. Sende sie und lies, was zurückkommt: ein weiteres Retry-After, wenn sie abgewiesen wird, oder im kostenlosen Tarif die Header, sobald sie bedient ist.
Rate-Limits schützen keinen Schlüssel, den du aus den Augen verloren hast. Ein geleakter Schlüssel zieht von denselben Limits ab wie jeder andere Schlüssel in deinem Konto, und er kann alles, was seine Scopes erlauben. Ihn zu widerrufen erstattet keine Aufrufe, die er schon gemacht hat. Wenn du dir bei einem Schlüssel unsicher bist, widerrufe ihn. Siehe Sicherheit und Schlüsselverwaltung weiter unten.
Konventionen
Antwortfelder sind camelCase. Bei Query-Parametern spielt die Groß- und Kleinschreibung keine Rolle, camelCase funktioniert dort also ebenfalls — die veröffentlichte Spezifikation schreibt sie PascalCase, deshalb begegnen dir beide Formen.
Ein Feld, das einen Kalendertag nennt, ist YYYY-MM-DD. Ein Feld, das einen Zeitpunkt nennt, ist ISO 8601 mit Zeitzonenversatz.
Seitengrößen werden gekappt, nicht abgelehnt. Frag ein pageSize von 500 an, und du bekommst 100 Zeilen und ein 200, keinen Fehler — lies pagination.pageSize also aus der Antwort zurück, statt dich auf das zu verlassen, was du geschickt hast.
Eine Antwort kann Felder tragen, die diese Seite nicht aufführt. Ignorier die, die du nicht kennst, statt daran zu scheitern — das hält deinen Client am Laufen, während die API wächst.
REST ist schlichtes HTTP, für den Aufruf braucht es also kein SDK — jede Sprache mit einem HTTP-Client reicht aus. Es gibt nichts zu installieren.
Versionierung und Änderungen
Alles, was hier dokumentiert ist, fällt unter diese Richtlinie.
Es gibt keine Versionsnummer im Pfad und keinen Versions-Header. Jeder Endpunkt hat eine aktive Version, und das ist die hier dokumentierte.
Was wir ohne Ankündigung ändern dürfen
Nichts davon bricht einen Client, der sich an die Konventionen oben hält.
Einen Endpunkt hinzufügen, oder eine Operation auf einem bestehenden.
Ein Feld zu einer Antwort hinzufügen.
Einen optionalen Parameter hinzufügen. Lass ihn weg, und nichts ändert sich.
Einen Wert zu einer festen Auswahl hinzufügen, etwa einen Status oder einen Typ.
Einen Antwort-Header hinzufügen.
Was wir nicht ohne Ankündigung ändern
Jedes davon kann einen laufenden Client brechen.
Einen Endpunkt entfernen, oder seinen Pfad oder seine Methode ändern.
Ein Antwortfeld entfernen oder umbenennen.
Den Typ eines Feldes oder seine Bedeutung ändern.
Einen heute optionalen Parameter zur Pflicht machen.
Eingaben ablehnen, die heute akzeptiert werden.
Den Scope ändern, den ein Endpunkt braucht.
Vor jeder dieser Änderungen steht es mindestens 90 Tage vorher im Changelog, zusammen mit dem, was du anpassen musst. Was heute funktioniert, funktioniert bis dahin weiter.
Änderungen werden im Changelog angekündigt, verlinkt im Abschnitt „Changelog“ unten. E-Mail oder Feed gibt es noch nicht, schau also dort nach, wenn du Arbeit gegen die API planst.
Solange die API in der Beta ist, wächst der dokumentierte Umfang weiter. Was schon hier steht, bricht dir nichts ohne Vorwarnung.
Changelog
Neuerungen der Era Developer Platform, einschließlich der Era API, neueste zuerst. Die Richtlinie oben sagt, was vorgewarnt wird und wie lange; im Changelog stehen diese Vorwarnungen.
Sicherheit und Schlüsselverwaltung
Einen Agenten freizugeben erzeugt einen Schlüssel
Wenn du einen Agenten per OAuth freigibst, erstellt Era ihm einen API-Schlüssel. Er landet in derselben Dashboard-Liste wie die, die du selbst anlegst, unter einem Namen, den Era aus dem Namen des Clients bildet.
Wie er heißt
Auto -- ClaudeEr trägt genau die Scopes, die du auf diesem Bildschirm freigegeben hast, und sonst nichts. Widerrufe ihn im Dashboard, und der Agent bekommt keinen neuen Zugriff, bis du ihn erneut freigibst. Ein Token, das er schon hat, funktioniert weiter, bis es abläuft — höchstens eine Stunde.
Schreibzugriffe stehen in deinem Aktivitätsprotokoll, Lesezugriffe nicht
Das Erstellen und das Widerrufen eines Schlüssels stehen beide in deinem Aktivitätsprotokoll, ebenso jeder Tool-Aufruf, den ein Agent über MCP macht. Ein REST-Schreibzugriff steht ebenfalls darin — als die Änderung, die er gemacht hat, etwa ein angelegter Tag oder eine bearbeitete Transaktion. Ein REST-Lesezugriff erzeugt überhaupt keinen Eintrag. Era schreibt diese Einträge in jedem Tarif mit, aber um das vollständige Protokoll zu lesen, brauchst du Organize oder höher — darunter siehst du nur die neuesten Einträge. Auch beim Schreiben führt REST kein Protokoll pro Request: festgehalten wird die Änderung, nicht der Aufruf, und sie steht unter deinem Konto, nicht unter dem Schlüssel, der sie gemacht hat.
Wenn du dir bei einem Schlüssel je unsicher bist, widerrufe ihn. Ein selbst erstellter Schlüssel funktioniert ab seiner nächsten Anfrage nicht mehr, auf REST wie auf MCP. Der Schlüssel eines Agenten bekommt sofort keinen neuen Zugriff mehr, und ein Token, das er schon hat, läuft innerhalb einer Stunde ab. Ein Ersatz ist in einer Minute erstellt.
- Scopes sind grob
- banking:read deckt weit mehr ab als die sechs Lesezugriffe auf dieser Seite — derselbe Scope deckt auch alle übrigen Lesezugriffe deines Kontos ab: Salden, Positionen, Verbindungen, Ausgaben. Ein Scope, enger geht es nicht. Schreib-Scopes stehen ebenfalls zur Auswahl — behandle also jeden Schlüssel wie ein Passwort. Er handelt als dein Konto, nicht nur als ein Ausschnitt davon. banking:write kann Kategorien, Tags und Transaktions-Metadaten ändern, manuelle Konten und Salden verwalten und Institute verbinden oder trennen — kein Scope auf dieser Seite kann Geld zwischen deinen Bankkonten bewegen.
- Scopes aktualisieren sich nicht
- Die Scopes eines Schlüssels stehen beim Erstellen fest und ändern sich danach nie. Das ist für alles wichtig, was ein Scope abdeckt und noch nicht aktiviert ist: gib social:write heute frei, und der Schlüssel hat ihn auch dann noch, wenn es geteilte Ansichten gibt. Gib frei, was du jetzt nutzt, nicht was du vielleicht nutzen wirst.
- Keine Freigabe nötig
- Du bist bereits in deinem eigenen Konto angemeldet, deshalb braucht das Erstellen eines Schlüssels keine fremde Zustimmung — es gibt keine Prüfung und keine Warteliste, und niemand bei Era gibt die Anfrage frei. Es wird sofort in dein Aktivitätsprotokoll geschrieben, sodass ein unbekannter Schlüssel leicht auffällt.
- Bank-Login bleibt unerreichbar
- Ein Schlüssel erreicht dein Bank-Login nicht, weil Era es nie hat. Du gibst es in der Verbindungsstrecke des Datenanbieters ein, nicht auf einem Era-Bildschirm — was Era danach behält, ist ein mit AES-256 verschlüsseltes Zugriffstoken pro Verbindung, das du durch Trennen der Bank wegwerfen kannst.
- Schlüssel werden gehasht, nicht gespeichert
- Dein Schlüssel besteht aus 256 Bit Zufallsdaten und wird vor dem Speichern mit SHA-256 gehasht. Wir behalten den Hash, nicht den Schlüssel. Verlierst du ihn, widerrufst du ihn und erstellst einen neuen.
Kernressourcen
Konten
Jedes Konto, das du sehen kannst, über alle verbundenen Banken hinweg, und daneben die Zahl der ausgelassenen: excludedAccountCount, aufgeteilt in tierExcludedAccountCount für die Konten, die das Kontolimit deines Tarifs auslässt, und userExcludedAccountCount für die, die du ausgeblendet hast. accountLimit ist, wie viele Konten dein Tarif gleichzeitig zeigt, über alle deine Verbindungen hinweg. accountLimitLift nennt den günstigsten Tarif, der Platz für jedes Konto hat, das du nicht ausgeblendet hast, und ist null, wenn dein Tarif nichts auslässt. Jedes Konto trägt seinen accountGroupKey — den Wert, den der Salden-Endpunkt in seinem Pfad nimmt — und die connectionId, zu der es gehört, deshalb ist das der erste Aufruf. Nimmt connectionId, um auf eine einzelne Verbindung einzugrenzen (die Zahlen grenzen sich mit ein, accountLimit und accountLimitLift nicht), und includeExcluded, um die Konten hereinzuholen, die dein Tarif auslässt, und die, die du ausgeblendet hast.
- connectionIdoptional
- Grenzt die Liste auf die Konten einer Verbindung ein.
- includeExcludedoptional
- Bezieht auch die Konten mit ein, die dein Tarif auslässt, und die, die du ausgeblendet hast, mit zurückgehaltenen Salden. Das Feld visibility jeder Zeile sagt, welcher Fall es ist: tierExcluded oder userExcluded, und visible bei allen anderen. Der Salden-Endpunkt schreibt diese Werte anders, also nutze nicht einen Parser für beide. excludedAccountCount kommt auch dann zurück, wenn das hier true ist, und diese Konten stehen schon in der Liste, also zähl die beiden nicht zusammen. Standardmäßig false.
{
"accounts": [
{
"accountGroupKey": "uagr_7f3c9a21",
"connectionId": "ucon_4b19e02c",
"name": "Everyday Checking",
"currentBalance": 4820.16,
"supportsTransactions": true,
…
}
],
"excludedAccountCount": 1
}Bei einem Konto, das du ausgeblendet hast oder das dein Tarif ausschließt, kommen die Saldenfelder als null zurück und nicht als Null — null heißt zurückgehalten, nicht leer. supportsTransactions ist null im selben Sinn: Era kann es nicht sagen, und nie heißt es, die Antwort sei nein. Genauso bei den Tariffeldern: Wenn Era deinen Tarif bei dieser Anfrage nicht lesen konnte, kommen tierExcludedAccountCount, userExcludedAccountCount, accountLimit und accountLimitLift alle als null zurück. accountLimit ist außerdem null bei einem Tarif ohne Kontolimit, und accountLimitLift, wenn kein Tarif mehr Platz hat oder dein Tarif nichts auslässt.
Kontosaldo
One account's balance, with the credit fields filled in when the account is a liability. The path takes that account's accountGroupKey — the same value /banking/accounts returns for it. The key is not checked for shape before the lookup, so a malformed key and an unknown one answer the same way.
{
"accountGroupKey": "uagr_7f3c9a21",
"currentBalance": 4820.16,
"availableBalance": 4712.03,
"creditLimit": null,
"currencyCode": "USD",
"availableCredit": null,
"asOf": "2026-08-11T09:32:00Z",
"visibility": null
}Ein ausgeblendetes Konto, oder eines, dessen Verbindung gekappt wurde, antwortet trotzdem mit 200 — mit den Saldenfeldern auf null. Ein 404 heißt, dass es das Konto wirklich nicht gibt oder der Schlüssel nicht die Form eines Schlüssels hatte. Achte hier auf das Feld visibility: Es ist null, wenn das Konto sichtbar ist, tier_excluded, wenn das Kontolimit deines Tarifs es auslässt, user_excluded, wenn du es ausgeblendet hast, und connection_severed, wenn seine Verbindung gekappt wurde. Bei tier_excluded ist accountLimit das Limit deines Tarifs, und accountLimitLift nennt den günstigsten Tarif, der Platz für jedes Konto hat, das du nicht ausgeblendet hast, dieses eingeschlossen. Bei jedem anderen Zustand ist accountLimitLift null, und bei connection_severed ist auch accountLimit null.
Kontoübersicht
Summen über die Konten, die du sehen kannst: totalAssets, totalLiabilities und netWorthHint, also das erste minus dem zweiten. Nimmt keine Parameter.
{
"userId": "7d1c0b93a8e24f60",
"accounts": [ … ],
"totalVisibleCount": 6,
"totalHiddenCount": 2,
"totalAssets": 48210.75,
"totalLiabilities": 9327.40,
"netWorthHint": 38883.35,
"computedAt": "2026-08-11T09:32:00Z"
}netWorthHint zählt nur die Konten in dieser Antwort, deshalb sagt dir totalHiddenCount, was ihm fehlt: tierExcludedAccountCount davon lässt das Kontolimit deines Tarifs aus, und userExcludedAccountCount hast du selbst ausgeblendet. accountLimitLift nennt den günstigsten Tarif, der die erste Sorte zurückholt, und ist null, wenn es keine gibt. Nimm netWorthHint als Ausgangszahl und nicht als verbindliches Nettovermögen.
Transaktionen
Deine Transaktionen, seitenweise, eingepackt zusammen mit den Seitenzahlen. Nimmt page und pageSize (100 ist die Obergrenze), dazu optionale Filter nach Konto, Zeitraum, angewendeten Regeln und vergebenen Tags.
- accountIdoptional
- Grenzt auf die Transaktionen eines Kontos ein, über dessen accountGroupKey.
- fromDateoptional
- Nur Transaktionen an oder nach diesem Datum.
- toDateoptional
- Nur Transaktionen an oder vor diesem Datum.
- pageoptional
- Seitenzahl, ab 1 gezählt. Standardmäßig 1.
- pageSizeoptional
- Zeilen pro Seite. Standardmäßig 50, auf 100 begrenzt.
- sortByoptional
- Feld für die Sortierung: transactionDate, amount, description, category oder merchantName.
- sortDirectionoptional
- asc oder desc. Standardmäßig absteigend.
- categoryKeysoptional
- Only transactions in these categories, by their fcat_ keys. Takes a list, not a single key, and a transaction matches if its effective category is any one of them. Send the literal "uncategorized" to select the transactions that have no category at all.
- searchoptional
- Volltextsuche über Händler, Beschreibung, Kategorie, Kontoname und Betrag.
- ruleIdsoptional
- Nur Transaktionen, die eine Automatisierungsregel berührt hat, über den Schlüssel der Regel.
- tagKeysoptional
- Nur Transaktionen mit einem dieser Tags.
- reviewStatusesoptional
- needs_review, reviewed oder flagged. Nimmt eine Liste; eine Transaktion passt, wenn ihr Prüfstatus einer davon ist.
- includeChildrenoptional
- With a category filter set, also include transactions in the subcategories of every key you passed. Defaults to false.
- includePendingoptional
- Gibt zusätzlich ausstehende Buchungen der letzten 7 Tage zurück, gekennzeichnet mit isPending. Standardmäßig false. Ausstehende Zeilen sind schreibgeschützt.
{
"transactions": [ … ],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalItems": 412,
"totalPages": 21
},
"historyWindowApplied": true,
"historyWindowFloorDate": "2026-06-28",
"historyWindowHiddenCount": 137,
"historyWindowEarliestDate": "2024-03-02",
"historyWindowDegraded": false
}Dein Tarif kann eine Verlaufsfenster-Grenze anwenden, die ältere Transaktionen verbirgt. Deshalb trägt die Antwort die historyWindow-Felder: historyWindowApplied sagt dir, dass eine Grenze tatsächlich etwas verborgen hat, historyWindowFloorDate, wo sie liegt, historyWindowHiddenCount, wie viele Zeilen dahinter stehen, und historyWindowEarliestDate, wie weit dein Verlauf wirklich zurückreicht. Ohne sie ist ein kurzes Ergebnis nicht von einem Konto ohne ältere Transaktionen zu unterscheiden. Zwei davon ändern, was du schreibst: historyWindowHiddenCount kann null sein, auch wenn eine Grenze gegriffen hat — lies null also als unbekannt und nicht als die Zahl 0; und wenn historyWindowDegraded true ist, konnte Era deinen Tarif bei dieser Anfrage nicht bestätigen, das Grenzdatum ist dann eine Schätzung und keine Tatsache. Bei einer bestätigten bezahlten Anfrage greift keine Grenze, und historyWindowApplied kommt als false zurück. Auch das Kontolimit deines Tarifs lässt Transaktionen aus: tierExcludedAccountCount sagt, wie viele deiner Konten es aus dieser Anfrage heraushält, und userExcludedAccountCount, wie viele du ausgeblendet hast — beide auf das Konto eingegrenzt, nach dem du gefiltert hast, falls du das getan hast. Beide sind null, wenn Era deinen Tarif bei dieser Anfrage nicht lesen konnte.
Durch eine lange Historie zu blättern verbraucht Anfragen. Dein Tarif begrenzt, wie schnell du aufrufen kannst, und im kostenlosen Tarif, wie viele Aufrufe du pro Tag bekommst. Unter Limits stehen die Zahlen pro Tarif, die Rate-Limit-Header und was ein 429 dir sagt.
Eine Transaktion ändern
Vier Dinge an einer Transaktion kannst du überschreiben: ihre Kategorie, den Händlernamen, eine eigene Notiz und ihren Prüfstatus. Schick nur die, die du änderst — was du weglässt, bleibt unverändert. Die id im Pfad ist der utgr_-Schlüssel der Transaktion. Verändert Daten, deshalb ist banking:write statt banking:read nötig.
- categoryKeyoptional
- Der fcat_-Schlüssel der zuzuweisenden Kategorie. Lässt du ihn weg, behält die Transaktion ihre bisherige Kategorie.
- merchantNameoptional
- Ein eigener Händlername, bis zu 1000 Zeichen. Lässt du ihn weg, bleibt der aktuelle Name bestehen.
- descriptionoptional
- Eine eigene Notiz zu dieser Transaktion, bis zu 5000 Zeichen. Lässt du sie weg, bleibt die aktuelle Notiz bestehen.
- clearCategoryoptional
- Verwirft deine Kategorie-Überschreibung, sodass Eras eigene Kategorisierung wieder greift. Standardmäßig false.
- clearMerchantNameoptional
- Verwirft deine Überschreibung des Händlernamens, sodass der von deiner Bank gesendete Name zurückkehrt. Standardmäßig false.
- clearDescriptionoptional
- Verwirft deine Beschreibungs-Überschreibung, sodass die von deiner Bank gesendete Beschreibung zurückkehrt. Standardmäßig false.
- reviewStatusoptional
- Markiert sie als needs_review, reviewed oder flagged.
- clearReviewStatusoptional
- Verwirft deine Überschreibung des Prüfstatus. Standardmäßig false.
{
"transaction": { … }
}Du bekommst die gesamte aktualisierte Transaktion zurück, in derselben Form, die die Liste oben liefert — hier nicht erneut abgedruckt, weil es ein großes Objekt ist, das sich noch verändert. Setzt du ein Feld und leerst es im selben Aufruf, kommt 400 zurück. Eine Transaktion, die dir nicht gehört, oder die es gar nicht gibt, kommt als 403 zurück — die API unterscheidet die beiden Fälle nicht. Und hat etwas anderes dieselbe Zeile geändert, während du geschrieben hast, bekommst du 409: lies sie erneut und schick sie erneut.
Bis zu 100 auf einmal ändern
Dieselben vier Überschreibungen, angewendet auf eine Liste von Transaktionen in einem Aufruf. Jede id in der Liste bekommt dieselben Änderungen — es gibt keine Variation pro Transaktion. Verändert Daten, deshalb ist banking:write statt banking:read nötig.
- transactionIds
- Die utgr_-Schlüssel der zu ändernden Transaktionen. Mindestens einer, höchstens 100. Über 100 wird abgelehnt statt gekappt — anders als pageSize oben bekommst du ein 400, und es ändert sich gar nichts.
- categoryKeyoptional
- Der fcat_-Schlüssel der zuzuweisenden Kategorie. Lässt du ihn weg, behält die Transaktion ihre bisherige Kategorie.
- merchantNameoptional
- Ein eigener Händlername, bis zu 1000 Zeichen. Lässt du ihn weg, bleibt der aktuelle Name bestehen.
- descriptionoptional
- Eine eigene Notiz zu dieser Transaktion, bis zu 5000 Zeichen. Lässt du sie weg, bleibt die aktuelle Notiz bestehen.
- clearCategoryoptional
- Verwirft deine Kategorie-Überschreibung, sodass Eras eigene Kategorisierung wieder greift. Standardmäßig false.
- clearMerchantNameoptional
- Verwirft deine Überschreibung des Händlernamens, sodass der von deiner Bank gesendete Name zurückkehrt. Standardmäßig false.
- clearDescriptionoptional
- Verwirft deine Beschreibungs-Überschreibung, sodass die von deiner Bank gesendete Beschreibung zurückkehrt. Standardmäßig false.
- reviewStatusoptional
- Markiert sie als needs_review, reviewed oder flagged.
- clearReviewStatusoptional
- Verwirft deine Überschreibung des Prüfstatus. Standardmäßig false.
{
"transactions": [ … ]
}Du bekommst die aktualisierten Transaktionen zurück, in derselben Form, die die Liste oben liefert. Setzt du ein Feld und leerst es im selben Aufruf, kommt 400 zurück, ebenso bei einer leeren Liste. Eine Liste, die eine Transaktion enthält, die dir nicht gehört oder die es gar nicht gibt, kommt für den gesamten Aufruf als 403 zurück — nichts wird geändert. Hat etwas anderes eine dieser Zeilen geändert, während du geschrieben hast, bekommst du 409: lies sie erneut und schick sie erneut.
Kategorien
Die gesamte Kategorien-Taxonomie: jede Kategoriengruppe, mit ihren Unterkategorien darin verschachtelt. Die Taxonomie ist gemeinsam, nicht pro Konto.
{
"packs": [
{
"packSlug": "default",
"packName": "Era default categories",
"isDefault": true,
"categories": [
{
"projectionKey": "fcat_food_dining",
"categoryName": "Food & dining",
"isTopLevel": true,
"children": [ … ]
}
]
}
],
"meterLimit": 25,
"canCreateCustomCategories": true
}Eine Kategorie anlegen
Eine benutzerdefinierte Kategorie unter einem bestehenden Elternteil. Verändert Daten, deshalb ist banking:write statt banking:read nötig.
- slug
- URL-sicherer Bezeichner — Kleinbuchstaben, Ziffern und Bindestriche, 2 bis 50 Zeichen.
- parentCategoryKey
- Der fcat_-Schlüssel der Kategorie, unter der diese eingehängt wird.
- name
- Anzeigename.
- descriptionoptional
- Optionale Beschreibung.
- iconNameoptional
- Optionaler Icon-Name.
- spendingTypeoptional
- Optionale Ausgabenklassifizierung.
- displayOrderoptional
- Optionale Sortierposition unter den Geschwisterkategorien.
- assignmentEligibilityoptional
- Optionale Regel dafür, welchen Transaktionen diese Kategorie zugewiesen werden darf.
- sourceSystemKeysoptional
- Optionale Liste bestehender Kategorie-Schlüssel, deren Transaktionen künftig hierher geleitet werden sollen.
- applyRetroactivelyoptional
- Bei true werden auch vergangene Transaktionen gegen das neue Routing neu bewertet. Standardmäßig false.
{
"categoryKey": "fcat_side_hustle_9f2a",
"overlayProjectionKey": "fcov_9f2a1c",
"action": "created",
"isQuotaExceeded": false,
"createdMappingRuleKeys": [ … ],
…
}Die Antwort trägt außerdem retroactiveAffectedCount, mergeSourcesHiddenCount und mergeSourcesTotalCount — Felder, die dieser Aufruf mit Kategorien-Zusammenführungen teilt und die hier nicht gezeigt werden — sowie isQuotaExceeded, quotaExceededMessage und meterGate, die bei einer angelegten Kategorie immer false, null und null sind. Lehnt das Kontingent deines Tarifs die Neuanlage ab, kommt stattdessen ein 402 ohne diese Felder: Sein Body besteht aus statusCode, message und errors.generalErrors, dessen einziger Eintrag sagt, an welches Limit du gestoßen bist.
Tags
Alle Tags deines Kontos, als eine Liste. Keine Seitenaufteilung — eine Antwort gibt dir alle zurück.
- tagTypeoptional
- Filtert nach Tag-Herkunft: user, system oder auto.
- includeDeletedoptional
- Bezieht gelöschte Tags mit ein. Standardmäßig false.
{
"tags": [
{
"tagKey": "utag_9c2f01ab",
"name": "business-expense",
"displayName": "Business expense",
"tagType": "user",
"color": "#6DC6BA",
"transactionCount": 42
}
]
}Einen Tag anlegen
A new tag, canonicalized to lowercase. Mutating, so it needs banking:write rather than banking:read. System tags cannot be created through the API; user and auto tags can.
- name
- Der kanonische Name des Tags.
- displayNameoptional
- Optionaler Anzeigename. Standardmäßig der kanonische Name.
- tagTypeoptional
- user or auto. Defaults to user. system is refused — it is reserved for tags Era creates itself.
- coloroptional
- Optionale Hex-Farbe für die Anzeige.
- iconoptional
- Optionaler Icon-Name.
{
"tag": {
"tagKey": "utag_9c2f01ab",
"name": "business-expense",
"displayName": "Business expense",
"tagType": "user",
"version": 1,
"createdAt": "2026-08-26T09:15:00Z"
}
}