Vai al contenuto principale
PrezziAziendaAccedi
Inizia gratis

API di Era

Scopri gli endpoint disponibili, le intestazioni di autenticazione, la paginazione e i limiti dell'API Era.

Ultimo aggiornamento: 26 agosto 2026

Ancora in beta

Questi endpoint funzionano già oggi, ma l'API è ancora in evoluzione, quindi alcuni dettagli potrebbero cambiare. Controlla la data dell'ultimo aggiornamento in alto per vedere quando questa pagina è stata rivista l'ultima volta.

Avvio rapido

Prima di iniziare ti serve un account Era con almeno un istituto collegato: senza una connessione questi endpoint non hanno niente da restituire.

  1. 1

    Accedi a Era e collega un istituto, se non l'hai già fatto.

  2. 2

    Apri le tue chiavi API nella dashboard e creane una. All'inizio sono spuntati tutti gli scope, quindi togli la spunta a quelli che non ti servono — per questi endpoint resta banking:read. Scegli anche una scadenza; non esiste un'opzione senza scadenza.

  3. 3

    Copia la chiave. Viene mostrata una volta sola e non possiamo mostrartela di nuovo. Copiala e conservala in un posto sicuro, come un gestore di segreti. Se perdi una chiave, non puoi più vederla. Creane una nuova al suo posto.

  4. 4

    Mandala in un header insieme alla tua richiesta.

cURL

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

Risposta · 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
}

Autenticazione

Invia la tua chiave in uno di questi due modi:

Metodi di autenticazione
MetodoCredenziale
HeaderX-API-Key: fmk_your_key_here
Token bearerAuthorization: Bearer fmk_your_key_here

Ogni richiesta è cifrata con TLS.

Le chiavi scadono, e quando ne crei una scegli tu tra quanto. La durata massima disponibile è di 90 giorni sul piano gratuito e di 365 su uno a pagamento: non esiste un'opzione senza scadenza, quindi qualsiasi cosa tu costruisca su questo ha bisogno di un piano per ruotare la chiave prima che scada.

Header di risposta

Ogni risposta include:

Header di risposta
HeaderDescrizione
fly-request-id

Un identificativo univoco della richiesta. Includilo quando contatti il supporto per una richiesta specifica — vedi ID richiesta

Errori

L'API restituisce questi codici di stato di errore:

  • 400

    Input malformato: un parametro sbagliato, un aggiornamento massivo vuoto o con più di 100 elementi, o una scrittura che imposta e cancella lo stesso campo nella stessa chiamata.

  • 401

    Nessuna chiave, o una che non si può interpretare. Inviala nell'intestazione X-API-Key o come token bearer.

  • 402

    Una quota del piano è d'intralcio — oggi succede solo con la creazione di categorie.

  • 403

    La chiave non porta lo scope di cui questa chiamata ha bisogno — oppure, su una delle due scritture di transazioni, l'id appartiene a qualcun altro o non esiste affatto. L'API non distingue i due casi.

  • 409

    Qualcos'altro ha cambiato la riga mentre stavi scrivendo. Rileggila e reinvia la tua scrittura.

Forme di errore

Ogni errore torna nella stessa forma: statusCode, message e un oggetto errors che indica cosa non andava. Una chiave mancante o non valida può tornare senza alcun corpo.

Esempio

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

ID richiesta

Ogni risposta porta un'intestazione fly-request-id. Includila quando contatti il supporto per una richiesta specifica.

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 (scrittura)

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

Errori comuni

  • Impostare un campo e cancellarlo nella stessa scrittura — 400.

  • Più di 100 id in un aggiornamento massivo — 400, e non cambia nulla. Meno di uno è lo stesso.

  • Una transazione che non è tua, o che non esiste — 403, mai 404. Quindi la risposta non ti dice mai se un id esiste, solo che non è tuo da vedere.

  • Qualcos'altro ha cambiato la riga per primo — 409.

Limiti

Due dei dieci endpoint documentati limitano quanto puoi chiedere in una singola chiamata. Gli altri otto no.

Questo non significa illimitato: le chiavi continuano a scadere, le scritture hanno comunque limiti di lunghezza dei campi, e il tuo piano può comunque nascondere lo storico più vecchio. Niente di tutto questo è un rate limit — vedi sotto.

  • Account, saldo, riepilogo, categorie, tag e la scrittura di una singola transazione non hanno alcun limite di volume per chiamata. Ricevi l'intero insieme, oppure la singola riga che hai indicato.

  • pageSize è limitato a 100, non rifiutato. Chiedine di più e ricevi 100 righe con un 200 — leggi pagination.pageSize nella risposta invece di fidarti di ciò che hai inviato.

  • La scrittura massiva delle transazioni è limitata a 100 id, e a differenza di pageSize viene rifiutata anziché limitata: invia 101 e ricevi un 400, senza che nulla cambi.

  • Le chiavi scadono secondo il programma che scegli alla creazione — fino a 90 giorni nel piano gratuito, 365 in uno a pagamento. Non esiste un'opzione senza scadenza.

  • Il tuo piano può applicare un limite di finestra della cronologia che nasconde le transazioni più vecchie. La risposta delle transazioni porta i campi historyWindow che dicono se un limite si è applicato e dove è caduto.

  • I piani indicano anche un'assegnazione di richieste API — 500 nel piano gratuito, di più in ogni piano a pagamento.

Cosa manca: oggi su REST non c'è nessuna limitazione per richiesta, nessun 429, e nessuna intestazione di limite di frequenza — quindi una chiave trapelata non viene rallentata da nulla dal nostro lato. Se hai mai un dubbio su una chiave, revocala: la disattiva subito (vedi Sicurezza e gestione della chiave più sopra). E, dato che questa API è in beta, non dare per scontato che rimanga così.

Convenzioni

I campi delle risposte sono in camelCase. I parametri di query non distinguono maiuscole e minuscole, quindi lì funziona anche il camelCase: la specifica pubblicata li scrive in PascalCase, ed è per questo che in giro vedi entrambe le forme.

Un campo che indica un giorno di calendario è in formato YYYY-MM-DD. Un campo che indica un istante è in ISO 8601 con l'offset.

Le dimensioni delle pagine vengono limitate, non rifiutate. Chiedi un pageSize di 500 e ottieni 100 righe e un 200, non un errore: leggi quindi pagination.pageSize invece di fidarti di quello che hai mandato.

Una risposta può portare campi che questa pagina non elenca. Ignora quelli che non riconosci invece di fallire: è questo che tiene in piedi il tuo client mentre l'API cresce.

REST è semplice HTTP, quindi per chiamarlo non serve nessun SDK: va bene qualsiasi linguaggio con un client HTTP. Non c'è niente da installare.

Sicurezza e gestione delle chiavi

Approvare un agente crea una chiave

Quando approvi un agente tramite OAuth, Era crea una chiave API per lui. Finisce nella stessa lista della dashboard delle chiavi che crei tu, con un nome che Era genera dal nome del client stesso.

Come viene chiamata

Auto -- Claude

Porta esattamente gli scope che hai approvato su quella schermata, e nient'altro. Revocala dalla dashboard e l'agente smette di raggiungere il tuo account finché non lo approvi di nuovo.

Le semplici chiamate REST non vengono registrate

La creazione e la revoca di una chiave compaiono entrambe nel tuo registro attività, e lo stesso vale per ogni chiamata a uno strumento che un agente fa tramite MCP. Le singole chiamate REST no: lettura o scrittura che sia, oggi su quel percorso non c'è un log per singola richiesta.

Se hai un dubbio su una chiave, revocala. La revoca è immediata, taglia fuori la chiave sia su REST sia su MCP, e crearne un'altra richiede un minuto.

Altre cose da sapere prima di affidarti a una chiave.
FattoCosa significa
Gli scope sono grossolani

banking:read copre molto più delle sei letture di questa pagina — lo stesso scope copre anche il resto delle letture del tuo account: saldi, partecipazioni, connessioni, spese. Un unico scope, non esiste un'opzione più stretta. Anche gli scope di scrittura sono nel menu, come quelli di lettura — quindi tratta qualsiasi chiave come una password. Agisce come il tuo account, non come una sua parte. banking:write può modificare categorie, tag e metadati delle transazioni, gestire conti e saldi manuali e collegare o scollegare istituti — nessuno scope di questa pagina può spostare denaro tra i tuoi conti bancari.

Gli scope non si aggiornano

Gli scope di una chiave si fissano nel momento in cui la crei e non cambiano più. Questo conta per tutto ciò che uno scope copre ma che non è ancora attivo: concedi social:write oggi e la chiave ce l'ha ancora quando arrivano le viste condivise. Concedi quello che stai usando adesso, non quello che potresti usare più avanti.

Nessuna approvazione richiesta

Hai già effettuato l'accesso al tuo account, quindi creare una chiave non richiede l'approvazione di nessun altro: non c'è nessuna revisione e nessuna lista d'attesa, e nessuno in Era approva la richiesta. Viene scritta nel tuo registro attività non appena la crei, quindi una chiave che non riconosci è facile da individuare.

Le credenziali della banca restano fuori portata

Una chiave non può arrivare alle credenziali della tua banca, perché Era non le ha mai. Le inserisci nel flusso di connessione gestito dal fornitore di dati, non in una schermata di Era: quello che Era conserva dopo è un token di accesso per singola connessione, cifrato a riposo con AES-256, che puoi buttare via scollegando l'istituto.

Le chiavi vengono sottoposte a hash, non memorizzate

La tua chiave è fatta di 256 bit di dati casuali, sottoposti a hash SHA-256 prima di essere memorizzati. Conserviamo l'hash, non la chiave. Se la perdi, revocala e creane un'altra.

Risorse principali

Conti

GET/banking/accounts

Scope necessario

banking:read

Tutti i conti che riesci a vedere, su ogni istituto collegato, con accanto il conteggio di quelli rimasti fuori. Ogni conto porta con sé il suo accountGroupKey — il valore che l'endpoint del saldo accetta nel percorso — e il connectionId a cui appartiene, quindi è da questa chiamata che si parte. Accetta connectionId per restringere a una sola connessione e includeExcluded per far rientrare i conti che hai nascosto.

Parametri di query
connectionIdfacoltativo

Restringe l'elenco ai conti di una sola connessione.

includeExcludedfacoltativo

Include anche i conti esclusi per livello e quelli nascosti, con i saldi offuscati. Il default è false.

Risposta · 200

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

    }
  ],
  "excludedAccountCount": 1
}

Su un conto che hai nascosto o che il tuo piano esclude, i campi del saldo tornano null e non zero: null vuol dire trattenuto, non vuoto. supportsTransactions è null nello stesso spirito: vuol dire che Era non può dirlo, mai che la risposta sia no.

Saldo di un conto

GET/banking/accounts/{accountId}/balance

Scope necessario

banking:read

Il saldo di un singolo conto, con i campi del credito compilati quando il conto è una passività. Il percorso accetta l'accountGroupKey del conto — lo stesso valore che /banking/accounts restituisce per quel conto. Una chiave di un'altra forma viene rifiutata prima ancora che parta la ricerca.

Risposta · 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 conto nascosto, o uno la cui connessione è stata interrotta, risponde comunque 200 — con i campi del saldo a null. Solo un conto che davvero non c'è ti dà un 404. Qui tieni d'occhio il campo visibility: è null quando il conto è visibile, ed è una stringa come tier_excluded quando non lo è.

Riepilogo dei conti

GET/banking/accounts/summary

Scope necessario

banking:read

I totali sui conti che riesci a vedere: totalAssets, totalLiabilities e netWorthHint, che è il primo meno il secondo. Non accetta parametri.

Risposta · 200

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

netWorthHint conta solo i conti presenti in questa risposta, quindi è totalHiddenCount a dirti cosa gli manca. Trattalo come una cifra di partenza, non come un patrimonio netto definitivo.

Transazioni

GET/banking/transactions

Scope necessario

banking:read

Le tue transazioni, una pagina alla volta, avvolte in un contenitore che porta accanto i conteggi di paginazione. Accetta page e pageSize (100 è il massimo), più filtri opzionali per conto, intervallo di date, regole applicate e tag assegnati.

Parametri di query
accountIdfacoltativo

Restringe alle transazioni di un conto, tramite il suo accountGroupKey.

fromDatefacoltativo

Solo transazioni da questa data in poi.

toDatefacoltativo

Solo transazioni fino a questa data.

pagefacoltativo

Numero di pagina, a partire da 1. Il default è 1.

pageSizefacoltativo

Righe per pagina. Il default è 50, limitato a 100.

sortByfacoltativo

Campo per l'ordinamento: transactionDate, amount, description, category o merchantName.

sortDirectionfacoltativo

asc o desc. Il default è decrescente.

categoryKeyfacoltativo

Solo transazioni di una categoria, tramite la sua chiave fcat_.

searchfacoltativo

Ricerca full-text su commerciante, descrizione, categoria, nome del conto e importo.

ruleIdsfacoltativo

Solo transazioni toccate da una regola di automazione, tramite la chiave della regola.

tagKeysfacoltativo

Solo transazioni che portano uno di questi tag.

reviewStatusfacoltativo

needs_review, reviewed o flagged.

includeChildrenfacoltativo

Con categoryKey impostato, include anche le sue sottocategorie. Il default è false.

Risposta · 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
}

Il tuo piano può applicare un limite alla finestra di cronologia, che nasconde le transazioni più vecchie di quella soglia. È per questo che la risposta porta con sé i campi historyWindow: historyWindowApplied ti dice che un limite ha davvero nascosto qualcosa, historyWindowFloorDate è dove è caduto, historyWindowHiddenCount è quante righe ci sono dietro e historyWindowEarliestDate è fin dove arriva davvero la tua cronologia. Senza di loro un risultato corto è indistinguibile da un conto senza transazioni più vecchie. Due di questi cambiano il codice che scrivi: historyWindowHiddenCount può essere null anche quando un limite è stato applicato, quindi leggi null come sconosciuto e non come zero; e quando historyWindowDegraded è true, su quella lettura Era non è riuscita a confermare il tuo piano, quindi la data del limite è una stima e non un dato certo. Su una lettura a pagamento con il piano confermato non si applica nessun limite e historyWindowApplied torna false.

I piani indicano anche un massimale di richieste API: 500 sul piano gratuito, di più su ognuno di quelli a pagamento. I numeri attuali sono elencati insieme al resto dei limiti del tuo piano.

Modifica una transazione

Su una transazione puoi sovrascrivere quattro cose: la sua categoria, il nome del commerciante, una nota tua e il suo stato di revisione. Manda solo quelle che stai cambiando — tutto ciò che ometti resta com'è. L'id nel percorso è la chiave utgr_ della transazione. Modifica dati, quindi serve banking:write invece di banking:read.

PUT/banking/transactions/{id}

Scope necessario

banking:write
Corpo della richiesta
categoryKeyfacoltativo

La chiave fcat_ della categoria da assegnare. Ometti il campo e la transazione conserva la categoria che ha.

merchantNamefacoltativo

Un nome del commerciante scelto da te, fino a 1000 caratteri. Ometti il campo e il nome attuale resta invariato.

descriptionfacoltativo

Una nota tua su questa transazione, fino a 5000 caratteri. Ometti il campo e la nota attuale resta invariata.

reviewStatusfacoltativo

Impostalo su needs_review, reviewed o flagged.

clearCategoryfacoltativo

Rimuove la tua sovrascrittura della categoria, così torna a valere la categorizzazione di Era. Il default è false.

clearMerchantNamefacoltativo

Rimuove la tua sovrascrittura del nome del commerciante, così torna il nome che ha mandato la tua banca. Il default è false.

clearDescriptionfacoltativo

Rimuove la tua sovrascrittura della descrizione, così torna la descrizione che ha mandato la tua banca. Il default è false.

clearReviewStatusfacoltativo

Rimuove la tua sovrascrittura dello stato di revisione. Il default è false.

Risposta · 200

{
  "transaction": {}
}

Ricevi indietro l'intera transazione aggiornata, nella stessa forma restituita dall'elenco qui sopra — non ripetuta qui, perché è un oggetto grande e ancora in evoluzione. Impostare un campo e cancellarlo nella stessa chiamata dà 400. Una transazione che non è tua, o che non esiste affatto, dà 403 — l'API non distingue i due casi. E se qualcos'altro ha modificato la stessa riga mentre stavi scrivendo, ricevi 409: rileggila e rimandala.

Modifica fino a 100 alla volta

Le stesse quattro sovrascritture, applicate a un elenco di transazioni in un'unica chiamata. Ogni id nell'elenco riceve le stesse modifiche — non c'è variazione per singola transazione. Modifica dati, quindi serve banking:write invece di banking:read.

PUT/banking/transactions/bulk

Scope necessario

banking:write
Corpo della richiesta
transactionIds

Le chiavi utgr_ delle transazioni da modificare. Almeno una, e non più di 100. Oltre 100 viene rifiutato invece che troncato — a differenza di pageSize qui sopra, ricevi un 400 e non cambia nulla.

categoryKeyfacoltativo

La chiave fcat_ della categoria da assegnare. Ometti il campo e la transazione conserva la categoria che ha.

merchantNamefacoltativo

Un nome del commerciante scelto da te, fino a 1000 caratteri. Ometti il campo e il nome attuale resta invariato.

descriptionfacoltativo

Una nota tua su questa transazione, fino a 5000 caratteri. Ometti il campo e la nota attuale resta invariata.

reviewStatusfacoltativo

Impostalo su needs_review, reviewed o flagged.

clearCategoryfacoltativo

Rimuove la tua sovrascrittura della categoria, così torna a valere la categorizzazione di Era. Il default è false.

clearMerchantNamefacoltativo

Rimuove la tua sovrascrittura del nome del commerciante, così torna il nome che ha mandato la tua banca. Il default è false.

clearDescriptionfacoltativo

Rimuove la tua sovrascrittura della descrizione, così torna la descrizione che ha mandato la tua banca. Il default è false.

clearReviewStatusfacoltativo

Rimuove la tua sovrascrittura dello stato di revisione. Il default è false.

Risposta · 200

{
  "transactions": []
}

Ricevi indietro le transazioni aggiornate, nella stessa forma restituita dall'elenco qui sopra. Impostare un campo e cancellarlo nella stessa chiamata dà 400, e lo stesso vale per un elenco vuoto. Un elenco che contiene una transazione che non è tua, o che non esiste affatto, dà 403 per l'intera chiamata — non viene modificato nulla. Se qualcos'altro ha modificato una di quelle righe mentre stavi scrivendo, ricevi 409: rileggile e rimandale.

Categorie

GET/banking/categories

Scope necessario

banking:read

L'intera tassonomia delle categorie: ogni insieme di categorie, con le sue sottocategorie annidate dentro. La tassonomia è condivisa, non è per singolo conto.

Risposta · 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
}

Aggiungi una categoria

Una categoria definita dall'utente sotto un genitore esistente. Modifica dati, quindi serve banking:write invece di banking:read.

POST

Scope necessario

banking:write
Corpo della richiesta
slug

Identificatore adatto a un URL — lettere minuscole, numeri e trattini, da 2 a 50 caratteri.

parentCategoryKey

La chiave fcat_ della categoria sotto cui questa viene annidata.

name

Nome visualizzato.

descriptionfacoltativo

Descrizione facoltativa.

iconNamefacoltativo

Nome icona facoltativo.

spendingTypefacoltativo

Classificazione di spesa facoltativa.

displayOrderfacoltativo

Posizione d'ordine facoltativa tra le categorie sorelle.

assignmentEligibilityfacoltativo

Regola facoltativa su quali transazioni può ricevere questa categoria.

sourceSystemKeysfacoltativo

Elenco facoltativo di chiavi di categorie esistenti le cui transazioni dovranno essere instradate qui d'ora in poi.

applyRetroactivelyfacoltativo

Se true, rivaluta anche le transazioni passate secondo il nuovo instradamento. Il default è false.

Risposta · 201

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

}

La risposta porta anche retroactiveAffectedCount, mergeSourcesHiddenCount, mergeSourcesTotalCount e meterGate — campi che questa chiamata condivide con le fusioni di categorie e le creazioni limitate dalla quota, non mostrati qui.

Tag

GET/banking/tags

Scope necessario

banking:read

Tutti i tag del tuo account, in un unico elenco. Nessuna paginazione: una sola risposta li restituisce tutti.

Parametri di query
tagTypefacoltativo

Filtra per origine del tag: user, system o auto.

includeDeletedfacoltativo

Include i tag eliminati. Il default è false.

Risposta · 200

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

Crea un tag

Un nuovo tag, normalizzato in minuscolo. Modifica dati, quindi serve banking:write invece di banking:read — e può creare solo tag user; system non è consentito tramite l'API.

POST

Scope necessario

banking:write
Corpo della richiesta
name

Il nome canonico del tag.

displayNamefacoltativo

Nome visualizzato facoltativo. Il default è il nome canonico.

tagTypefacoltativo

Il default è user — l'unico valore che l'API accetta qui.

colorfacoltativo

Colore esadecimale facoltativo per la visualizzazione.

iconfacoltativo

Nome icona facoltativo.

Risposta · 201

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