Flowyer API

Riferimento API di Flowyer

Versione API: 25ac141b2e28

La descrizione completa della REST API di Flowyer per sviluppatori: endpoint, parametri, risposte ed esempi di codice.

Con la API di Flowyer il suo software o un assistente IA può leggere, creare e modificare record (pratiche, clienti, attività, ore di lavoro, costi e documenti) per conto di un utente Flowyer. Ogni richiesta viene eseguita esattamente con i permessi di quell'utente, ulteriormente limitati dagli ambiti della chiave o dell'autorizzazione. Tramite la API non è possibile eliminare nulla.

Le descrizioni degli endpoint e dei campi sono in inglese, perché gli assistenti IA leggono proprio questo testo.

URL di base

Tutti gli endpoint si trovano sotto gli indirizzi seguenti. Usi sempre esattamente l'host https che inizia con www., perché un reindirizzamento eliminerebbe l'intestazione Authorization.

URL di base

https://www.flowyer.it/api/agent
https://www.flowyer.hu/api/agent
https://www.flowyer.com/api/agent
https://www.flowyer.ro/api/agent
https://www.flowyer.de/api/agent

Autenticazione

Ogni richiesta richiede un token Bearer nell'intestazione Authorization. Esistono due tipi di token; gli endpoint li trattano allo stesso modo.

Chiave API personale

L'utente la crea in Flowyer in Impostazioni > Chiavi API, dopo che un amministratore dello studio ha abilitato la API. Una chiave inizia con flw_, viene mostrata una sola volta e può essere revocata in qualsiasi momento con effetto immediato.

OAuth 2.1 per le applicazioni collegate

Un'integrazione destinata ad altri utenti richiede l'accesso con il flusso OAuth 2.1 Authorization Code + PKCE (S256) invece di una chiave; i client possono registrarsi dinamicamente. Un token di accesso vale 60 minuti, un token di aggiornamento 60 giorni, e la coppia viene sostituita a ogni utilizzo. Il code_verifier PKCE contiene da 43 a 128 caratteri tra A-Z, a-z, 0-9 e - . _ ~ (RFC 7636 4.1), cioè base64url senza riempimento: una "=" finale viene rifiutata.

Metadati del server
https://www.flowyer.com/.well-known/oauth-authorization-server
Autorizzazione
https://www.flowyer.com/authorize
Token
https://www.flowyer.com/api/agent/oauth/token
Registrazione del client
https://www.flowyer.com/api/agent/oauth/register
Revoca
https://www.flowyer.com/api/agent/oauth/revoke

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/me' \
  -H 'Authorization: Bearer flw_...'

Ambiti

Ogni endpoint tranne GET /me richiede un ambito (scope). Se la chiave o l'autorizzazione non lo include, la risposta è 403 scope_missing. GET /me non richiede alcun ambito: serve a vedere cosa può fare la credenziale.

AmbitoSignificatoEndpoint
matters:read Lettura pratiche GETElenca le pratiche GETRisolvi la pratica per nome GETOttieni la pratica GETElenca i responsabili della pratica
matters:create Creazione pratiche POSTCrea una pratica
matters:update Modifica pratiche PATCHAggiorna la pratica POSTAggiungi un responsabile della pratica
clients:read Lettura clienti GETElenca i clienti GETRisolvi il cliente per nome GETOttieni il cliente
clients:create Creazione clienti POSTCrea un cliente
clients:update Modifica clienti PATCHAggiorna il cliente
tasks:read Lettura attività GETElenca le attività GETOttieni l'attività
tasks:create Creazione attività POSTCrea un'attività
tasks:update Modifica attività PATCHAggiorna l'attività POSTChiudi l'attività
workhours:read Lettura ore GETElenca le voci di tempo GETOttieni la voce di tempo
workhours:create Registrazione ore POSTRegistra una voce di tempo
workhours:update Modifica ore PATCHAggiorna la voce di tempo
costs:read Lettura costi GETElenca i costi GETOttieni il costo
costs:create Registrazione costi POSTRegistra un costo
costs:update Modifica costi PATCHAggiorna il costo
invoices:read Lettura fatture GETElenca le fatture GETOttieni la fattura
documents:read Elenco documenti (solo metadati, senza download) GETElenca i documenti della pratica GETElenca le cartelle della pratica
documents:download Download documenti (contenuto completo) GETScarica il documento
documents:create Caricamento documenti POSTCrea una cartella della pratica POSTAvvia il caricamento del documento POSTCompleta il caricamento del documento
documents:update Rinomina documenti PATCHRinomina il documento PATCHRinomina la cartella della pratica
colleagues:read Elenco dei colleghi (solo nomi) GETElenca i colleghi
knowledge:read Lettura della knowledge base GETElenca gli articoli della knowledge base GETOttieni l'articolo della knowledge base GETElenca le categorie della knowledge base GETOttieni la categoria della knowledge base
knowledge:create Creazione di voci nella knowledge base POSTCrea un articolo della knowledge base POSTCrea una categoria della knowledge base
knowledge:update Modifica di voci nella knowledge base PATCHAggiorna l'articolo della knowledge base PATCHAggiorna la categoria della knowledge base
emails:read Lettura email delle pratiche GETElenca le email della pratica GETOttieni l'email
litigation:read Elenco cronologia processuale GETElenca la cronologia processuale della pratica
litigation:create Creazione voce cronologia processuale POSTCrea una voce della cronologia processuale
litigation:update Modifica voce cronologia processuale PATCHAggiorna la voce della cronologia processuale
mail_register:read Lettura registro postale GETElenca il registro postale GETOttieni la voce del registro postale
mail_register:create Creazione voci registro postale POSTCrea una voce del registro postale
mail_register:update Modifica voci registro postale PATCHAggiorna la voce del registro postale
comments:read Lettura dei commenti del caso GETElenca i commenti della pratica
comments:create Pubblicazione di commenti al caso POSTPubblica un commento della pratica
comments:update Modifica dei propri commenti PATCHModifica un proprio commento della pratica
trials:read Lettura delle udienze GETElenca le udienze della pratica GETOttieni l'udienza
trials:create Creazione udienze POSTCrea un'udienza
trials:update Modifica udienze PATCHAggiorna l'udienza
courts:read Elenco dei tribunali GETElenca i tribunali
hr:read Lettura delle assenze (solo date) GETElenca le assenze del personale
calendar:read Lettura eventi del calendario GETElenca gli eventi del calendario GETOttieni l'evento del calendario
calendar:create Creazione eventi del calendario POSTCrea un evento del calendario
calendar:update Modifica eventi del calendario PATCHAggiorna l'evento del calendario
bookings:read Visualizzare le prenotazioni di appuntamenti GETElenca le prenotazioni GETOttieni la prenotazione
bookings:create Creare prenotazioni di appuntamenti (invia un'email al cliente) POSTCrea una prenotazione
bookings:update Riprogrammare e modificare le prenotazioni PATCHAggiorna la prenotazione
bookings:send Confermare o annullare prenotazioni (invia un'email al cliente) POSTConferma la prenotazione POSTAnnulla la prenotazione
tickets:read Lettura dei ticket di assistenza GETElenca i ticket GETOttieni il ticket
tickets:reply Rispondere ai ticket (invia un'e-mail al cliente) POSTRispondi al ticket
tickets:update Modifica dello stato del ticket PATCHCambia lo stato del ticket
portal:read Portale clienti: lettura di conversazioni e messaggi GETElenca i portali clienti GETElenca i messaggi del portale
portal:reply Portale clienti: rispondere al cliente (invia un messaggio e una e-mail di notifica) POSTRispondi nel portale clienti

Errori

Ogni errore ha la stessa struttura: un codice (error), un messaggio in inglese (message), il messaggio nella lingua dello studio (message_localized) e dettagli facoltativi (details). Con 401, 403, 404 e 422 non ha senso ripetere la richiesta invariata, con due eccezioni: con 404 upload_not_finished completi prima il caricamento su upload_url, poi richiami complete; con un token di accesso OAuth scaduto (401 expired_key) rinnovi prima il token.

HTTPerrorSignificato
400 invalid_json use_www_host bad_request Richiesta non valida: corpo JSON non valido, host errato (usare l'host www.) o richiesta illeggibile.
401 missing_key invalid_key revoked_key expired_key user_inactive office_not_found La chiave manca, non è valida, è revocata o scaduta, il suo titolare non è più attivo, oppure lo studio della chiave non è stato trovato.
403 scope_missing module_forbidden forbidden office_api_disabled licence_expired office_archived Manca un permesso sulla chiave o sull'utente, oppure lo studio non ha abilitato l'API.
404 not_found matter_not_visible unknown_endpoint upload_not_finished replay_not_visible Il record non esiste o l'utente non può vederlo; endpoint sconosciuto; il file caricato non è ancora arrivato nello storage (upload_not_finished: lo carichi su upload_url, poi richiami complete); oppure una creazione ripetuta il cui record era già stato creato ma nel frattempo è stato eliminato o nascosto (replay_not_visible: non è stato creato nulla di nuovo, non lo crei di nuovo).
405 delete_not_allowed update_not_allowed method_not_allowed Eliminare non è possibile tramite l'API; modificare solo dove la descrizione offre un'operazione PATCH.
409 client_exists client_exists_generic idempotency_key_reused duplicate_in_progress record_conflict record_locked duplicate_name Esiste già un cliente con quel nome; nella cartella esiste già un documento con quel nome (duplicate_name); il record è cambiato dopo la lettura (record_conflict: lo rilegga e reinvii la modifica con il nuovo updated_at); il record è stato fatturato o bloccato (record_locked: esegua la modifica in Flowyer); l'Idempotency-Key è stato usato su un'altra risorsa; oppure una richiesta identica è in elaborazione.
413 request_too_large file_too_large Il corpo della richiesta è troppo grande (request_too_large), oppure il file da caricare supera il limite (file_too_large; details.max indica il limite in byte).
422 validation_failed unknown_client unknown_colleague blocked_file_type upload_token_invalid folder_not_in_matter document_name_too_long Un campo non valido o mancante (details.fields indica quale); un token di caricamento non valido, già usato o scaduto (upload_token_invalid: ricominci il caricamento); oppure una cartella che non appartiene alla pratica (folder_not_in_matter).
429 rate_limited auth_rate_limited Troppe richieste (300 al minuto per chiave); l'intestazione Retry-After indica quando riprovare.
500 server_error Errore imprevisto. La richiesta è stata registrata con il suo request_id; riprovare più tardi e, se si ripete, comunicare questo ID all'assistenza Flowyer.
503 office_maintenance office_setup_incomplete temporarily_unavailable Lo studio non è temporaneamente disponibile (manutenzione o configurazione in corso); l'intestazione Retry-After indica quando riprovare.

Esempi di risposta · 403

{
  "error": "scope_missing",
  "message": "This API key does not have the \"clients:create\" permission. The permissions of an existing key cannot be changed, so the key owner needs to create a new key with this permission in Flowyer under Settings > API keys and use it in place of the old one.",
  "message_localized": "Questa chiave API non ha il permesso \"clients:create\". I permessi di una chiave esistente non possono essere modificati, quindi il titolare della chiave deve creare in Flowyer, in Impostazioni > Chiavi API, una nuova chiave con questo permesso e usarla al posto di quella vecchia.",
  "locale": "it",
  "details": {
    "required_scope": "clients:create"
  },
  "request_id": "3f0c8a5e-2b1d-4c7a-9e6f-5a4b3c2d1e0f"
}

Paginazione

Gli elenchi di record si sfogliano con i parametri limit e offset (predefinito 25, al massimo 100 elementi per pagina). pagination.total è il numero totale di risultati; l'offset della pagina successiva è l'offset precedente più limit. GET /colleagues, GET /clients/resolve e GET /matters/resolve non si sfogliano: accettano solo limit (con un valore predefinito e un massimo propri, si veda il singolo endpoint) e restituiscono total e truncated dentro data invece di un oggetto pagination, quindi non invii loro un offset.

Esempi di risposta · 200

{
  "data": [
    {
      "id": 1234,
      "...": "..."
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 134
  }
}

Ripetizioni sicure

Ogni creazione accetta un'intestazione Idempotency-Key (o un campo idempotency_key). Una richiesta ripetuta con lo stesso valore restituisce il record creato la prima volta (200, idempotent_replay) invece di crearne un altro. Chiavi diverse creano sempre record distinti. Senza chiave, una creazione identica entro 120 secondi restituisce il primo record.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/clients' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{"name": "Kovács Kft."}'

Modifiche e conflitti

Una modifica è una richiesta PATCH sul percorso del record: cambiano solo i campi inviati, e un null esplicito svuota un campo solo se la descrizione del campo lo consente; per alcuni campi il null mantiene il valore memorizzato, quindi legga la descrizione del campo. Invii in expected_updated_at il valore updated_at della sua ultima lettura. Se nel frattempo qualcun altro ha modificato il record, la risposta è 409 record_conflict; in tal caso rilegga il record.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/matters/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{"expected_updated_at": "2026-10-30T09:15:00+01:00", "description": null}'

Date e fuso orario

Le date hanno il formato AAAA-MM-GG, gli istanti seguono ISO 8601 con lo scostamento del fuso orario dello studio. Il fuso orario dello studio si trova nel campo office.timezone della risposta di GET /me.

Limiti

Al massimo 300 richieste al minuto per chiave o token; oltre, la risposta è 429 e l'intestazione Retry-After indica quando riprovare. Il corpo di una richiesta JSON può essere al massimo di 64 KB, un documento caricato al massimo di 100 MB.

Versioni

La versione della descrizione OpenAPI cambia a ogni modifica ed è inviata anche come intestazione ETag, così i client possono verificare con If-None-Match se è cambiata.

Identità

Chi sono

GET /api/agent/me

Restituisce l'utente e lo studio per conto dei quali agisce questa chiave API, gli scope della chiave (cosa può fare) e i limiti di frequenza. La richiami per prima per sapere quali operazioni sono disponibili; non richiede alcuno scope.

Questo endpoint non ha input.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
user
object
Campi di user
id
integer
name
string | null
language
string | null
office
object
Campi di office
id
integer
name
string | null
timezone
string

Zona IANA in cui l'API legge e scrive i timestamp, ad es. Europe/Budapest.

currency_id
integer

La valuta dello studio (id valuta Flowyer): costs.create contabilizza in essa quando currency_id è omesso.

currency
string | null

Codice ISO della valuta dello studio, ad es. HUF, EUR, RON.

key
object
Campi di key
id
integer
name
string

Nome che l'utente ha assegnato a questa chiave, oppure l'app connessa per un token OAuth.

kind
string

"key" = una chiave API statica, "oauth" = un token di accesso OAuth 2.1.

Valori ammessi: "key" "oauth"
prefix
string | null

Primi caratteri di una chiave statica, solo per identificazione; null per OAuth.

expires_at
string <date-time> | null
last_used_at
string <date-time> | null
scopes
string[]

Scope di questa credenziale, ad es. "matters:read". Un'operazione il cui scope è mancante risponde 403.

available_scopes
string[]

Tutti gli scope che il proprietario della chiave potrebbe abilitare in Flowyer.

limits
object
Campi di limits
requests_per_minute
integer
list_max_limit
integer
channel
string

Come la richiesta ha raggiunto Flowyer.

Valori ammessi: "rest" "mcp"
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Parametro di query sconosciuto (questa operazione non ne accetta nessuno); details.fields lo nomina.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/me' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "user": {
      "id": 1234,
      "name": "string",
      "language": "string"
    },
    "office": {
      "id": 1234,
      "name": "string",
      "timezone": "string",
      "currency_id": 1234,
      "currency": "string"
    },
    "key": {
      "id": 1234,
      "name": "string",
      "kind": "key",
      "prefix": "string",
      "expires_at": "2026-10-30T09:15:00+01:00",
      "last_used_at": "2026-10-30T09:15:00+01:00"
    },
    "scopes": [
      "string"
    ],
    "available_scopes": [
      "string"
    ],
    "limits": {
      "requests_per_minute": 0,
      "list_max_limit": 0
    },
    "channel": "rest"
  }
}

Colleghi

Elenca i colleghi

GET /api/agent/colleagues

Elenca i colleghi attivi dello studio (id, nome) per assigned_to_user_id / responsible_user_id. Con q (un nome così come ascoltato; accenti, maiuscole/minuscole e piccoli errori di battitura tollerati) risponde con lo stato exact/similar/none come gli strumenti resolve: solo "exact" è sicuro da usare direttamente.

Ambito
colleagues:read

Parametri di query

q
stringal massimo 255 caratteri

Nome di un collega da cercare, così come ascoltato o dettato, in qualsiasi ordine delle parole. Lo ometta per elencare tutti i colleghi attivi.

Esempio: "Nagy Péter"
limit
integer>= 1<= 500

Numero massimo di colleghi da restituire (predefinito 200).

Predefinito: 200

Risposte

200

OK.

dataobbligatorio
object
Campi di data
status
string | null

Solo con q: exact = una corrispondenza certa (sicuro usare il suo id), similar = corrispondenza approssimativa o più corrispondenze (prima confermi con l'utente), none = nessuna corrispondenza (chieda all'utente). Null senza q.

Valori ammessi: "exact" "similar" "none"
colleagues
object[]

Colleghi attivi, prima la corrispondenza migliore con q, altrimenti per nome.

Campi di colleagues
id
integer

Id utente: lo passi come assigned_to_user_id / responsible_user_id.

name
string

Nome visualizzato così come lo mostra Flowyer (con il titolo, se presente).

title
string | null

Prefisso del nome come "Dr.", oppure null.

total
integer

Quanti colleghi hanno corrisposto (tutti i colleghi attivi senza q) prima che l'elenco fosse ridotto a limit.

truncated
boolean

True quando hanno corrisposto più colleghi di quanti ne siano stati restituiti: restringa q o aumenti limit.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/colleagues?q=Nagy%20P%C3%A9ter' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "status": "exact",
    "colleagues": [
      {
        "id": 1234,
        "name": "string",
        "title": "string"
      }
    ],
    "total": 1,
    "truncated": true
  }
}

Pratiche

Elenca le pratiche

GET /api/agent/matters

Elenca le pratiche (cause) che l'utente può visualizzare, dalla più recente. La usi per trovare una pratica tramite numero di fascicolo, oggetto o cliente prima di farvi riferimento altrove. Le pratiche archiviate sono nascoste a meno che include_archived non sia true.

Ambito
matters:read
Permesso Flowyer
cases:read

Parametri di query

q
stringal massimo 100 caratteri

Ricerca a testo libero nell'oggetto e nei nomi dei clienti (accenti e maiuscole/minuscole ignorati) e negli altri numeri di fascicolo dello studio; oppure un numero di fascicolo, esattamente come restituito in case_number (lo schema di numerazione dello studio) o nel formato anno/sequenza come "2026/0025".

Esempio: "2026/0025"
client_id
integer>= 1

Solo le pratiche di questo cliente.

Esempio: 512
responsible_user_id
integer>= 1

Solo le pratiche di cui questo utente (id da colleagues.list) è responsabile: come responsabile principale, responsabile aggiuntivo o membro di un gruppo di lavoro responsabile (come il filtro colleghi del web).

updated_since
string <date-time>

Solo le pratiche modificate a partire da questo momento (ISO 8601).

Esempio: "2026-10-01T00:00:00+02:00"
include_archived
boolean

Includa le pratiche archiviate.

Predefinito: false
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters?q=2026%2F0025&client_id=512&updated_since=2026-10-01T00%3A00%3A00%2B02%3A00' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "case_number": "2026/0025",
      "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
      "status": "active",
      "case_type_id": 1234,
      "case_type": "string",
      "responsible_user_id": 1234,
      "responsible": "string",
      "clients": [
        {
          "id": 1234,
          "name": "string"
        }
      ],
      "started_on": "2026-10-30",
      "restricted": true,
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Risolvi la pratica per nome

GET /api/agent/matters/resolve

Trova una pratica tramite un oggetto o un nome cliente pronunciato o scritto in modo errato (accenti, maiuscole/minuscole e piccoli refusi tollerati). Restituisce lo stato exact/similar/none e i candidati. Solo "exact" è sicuro da usare direttamente; altrimenti confermi con l'utente. Molti casi simili non sono mai "exact": restringa con client_id o un nome più completo.

Ambito
matters:read
Permesso Flowyer
cases:read

Parametri di query

nameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Oggetto della pratica o nome del cliente da cercare, come ascoltato o dettato.

Esempio: "ingatlan adásvétel"
client_id
integer | null>= 1

Solo le pratiche di questo cliente (da usare dopo che clients.resolve ha restituito un cliente exact).

limit
integer>= 1<= 10

Numero massimo di candidati da restituire (valore predefinito 5).

Predefinito: 5

Risposte

200

OK.

dataobbligatorio
object
Campi di data
status
string

exact = una corrispondenza certa (sicuro usarne l'id). similar = una o più corrispondenze approssimative, confermi prima con l'utente. none = nessuna corrispondenza, chieda all'utente.

Valori ammessi: "exact" "similar" "none"
matters
object[]

Pratiche candidate, la corrispondenza migliore per prima.

Campi di matters
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
total
integer

Quante pratiche hanno corrisposto prima che l'elenco fosse ridotto a limit.

truncated
boolean

True quando hanno corrisposto più pratiche di quelle restituite, oppure esistevano troppi casi simili per verificarli tutti; restringa con client_id o un nome più completo, oppure aumenti limit, invece di scegliere da un elenco incompleto.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/resolve?name=ingatlan%20ad%C3%A1sv%C3%A9tel' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "status": "exact",
    "matters": [
      {
        "id": 1234,
        "case_number": "2026/0025",
        "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
        "status": "active",
        "case_type_id": 1234,
        "case_type": "string",
        "responsible_user_id": 1234,
        "responsible": "string",
        "clients": [
          {
            "id": 1234,
            "name": "string"
          }
        ],
        "started_on": "2026-10-30",
        "restricted": true,
        "created_at": "2026-10-30T09:15:00+01:00",
        "updated_at": "2026-10-30T09:15:00+01:00",
        "created_via_api": {
          "kind": "key",
          "key_id": 1234,
          "key_name": "string",
          "user_id": 1234,
          "user": "string",
          "at": "2026-10-30T09:15:00+01:00"
        }
      }
    ],
    "total": 1,
    "truncated": true
  }
}

Ottieni la pratica

GET /api/agent/matters/{id}

Restituisce una pratica (causa) con i suoi clienti e dettagli. Risponde 404 quando la pratica non esiste o l'utente non può visualizzarla.

Ambito
matters:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
description
string | null
litigious
boolean
archived_at
string <date> | null

Giorno in cui la pratica è stata archiviata, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "case_number": "2026/0025",
    "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
    "status": "active",
    "case_type_id": 1234,
    "case_type": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "clients": [
      {
        "id": 1234,
        "name": "string"
      }
    ],
    "started_on": "2026-10-30",
    "restricted": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "description": "string",
    "litigious": true,
    "archived_at": "2026-10-30"
  }
}

Crea una pratica

POST /api/agent/matters

Apre una pratica (causa) con il numero di fascicolo successivo dell'anno. Richiede almeno un cliente esistente (lo trovi o lo crei prima). L'avvocato responsabile è per impostazione predefinita l'utente della chiave e viene notificato in caso contrario. Parti, contatti e onorari si impostano in Flowyer.

Ambito
matters:create
Permesso Flowyer
cases:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

subjectobbligatorio
stringalmeno 2 caratterial massimo 255 caratteri

Titolo breve della pratica come appare negli elenchi. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
case_type_idobbligatorio
integer>= 1

Id del tipo di pratica (area del diritto) dall'elenco globale dei tipi di pratica di Flowyer: scelga quello il cui nome corrisponde alle parole dell'utente, oppure chieda all'utente di sceglierlo per nome. Un id sconosciuto risponde 422 con details.known_case_types (id + nome localizzato); una pratica esistente mostra il suo tipo in matters.get case_type_id / case_type.

client_idsobbligatorio
integer[]almeno 1 elemential massimo 20 elementi

Id dei clienti (mandanti). Almeno uno, al massimo 20.

Esempio: [ 512 ]
responsible_user_id
integer | null>= 1

Avvocato responsabile: un id utente da colleagues.list (vi cerchi un nome dettato). Valore predefinito: l'utente dietro la chiave.

started_on
string <date> | null

Data di inizio, YYYY-MM-DD. Valore predefinito: oggi.

Esempio: "2026-10-29"
description
string | nullal massimo 10000 caratteri

Descrizione più lunga, testo semplice.

main_case_number
string | nullal massimo 100 caratteri

Il numero di riferimento principale proprio dello studio per la pratica. Obbligatorio quando lo schema di numerazione dello studio lo utilizza (in caso contrario l'API risponde 422).

restricted
boolean

true = solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

Predefinito: false
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
description
string | null
litigious
boolean
archived_at
string <date> | null

Giorno in cui la pratica è stata archiviata, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
description
string | null
litigious
boolean
archived_at
string <date> | null

Giorno in cui la pratica è stata archiviata, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
  "case_type_id": 1234,
  "client_ids": [
    512
  ],
  "started_on": "2026-10-29"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "case_number": "2026/0025",
    "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
    "status": "active",
    "case_type_id": 1234,
    "case_type": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "clients": [
      {
        "id": 1234,
        "name": "string"
      }
    ],
    "started_on": "2026-10-30",
    "restricted": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "description": "string",
    "litigious": true,
    "archived_at": "2026-10-30"
  },
  "created": true
}

Aggiorna la pratica

PATCH /api/agent/matters/{id}

Modifica l'oggetto, la descrizione, la data di inizio, il flag contenzioso o l'avvocato responsabile di una pratica. Numero di fascicolo, muro cinese, stato di archiviazione, onorari e collegamenti ai clienti non sono modificabili qui. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409.

Ambito
matters:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

subject
string | nullalmeno 1 caratteri

Titolo breve della pratica. Testo semplice, al massimo 255 caratteri come NUOVO valore; nemmeno "<" e ">" possono essere introdotti, ma un oggetto memorizzato più lungo o che li contiene può essere restituito invariato. null mantiene l'oggetto attuale.

description
string | null

Descrizione più lunga, testo semplice, al massimo 10000 caratteri come NUOVO valore; una descrizione memorizzata più lunga può essere restituita invariata.

started_on
string <date> | null

Data di inizio, YYYY-MM-DD. null mantiene il valore attuale (una data di inizio non può essere cancellata).

litigious
boolean

Se la pratica è contenziosa.

responsible_user_id
integer | null>= 0

Nuovo avvocato responsabile: l'id utente di un collega attivo da colleagues.list. Viene notificato quando non è Lei. Inviare quello attuale, o null / 0, come viene restituita una pratica senza responsabile, non cambia nulla.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id della pratica. Lo usi come matter_id altrove.

Esempio: 1234
case_number
string

Numero di fascicolo come visualizzato in Flowyer, nello schema di numerazione dello studio.

Esempio: "2026/0025"
subject
string
Esempio: "Kovács Kft. v. Nagy Bt. - contract dispute"
status
string
Valori ammessi: "active" "archived"
case_type_id
integer | null
case_type
string | null

Nome localizzato del tipo di pratica.

responsible_user_id
integer | null
responsible
string | null

Nome visualizzato dell'avvocato responsabile.

clients
object[]

Clienti (mandanti) della pratica.

Campi di clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True quando solo gli avvocati responsabili possono visualizzare la pratica (muro cinese).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
description
string | null
litigious
boolean
archived_at
string <date> | null

Giorno in cui la pratica è stata archiviata, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/matters/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "subject": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "case_number": "2026/0025",
    "subject": "Kovács Kft. v. Nagy Bt. - contract dispute",
    "status": "active",
    "case_type_id": 1234,
    "case_type": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "clients": [
      {
        "id": 1234,
        "name": "string"
      }
    ],
    "started_on": "2026-10-30",
    "restricted": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "description": "string",
    "litigious": true,
    "archived_at": "2026-10-30"
  },
  "updated": true
}

Elenca i responsabili della pratica

GET /api/agent/matters/{id}/responsibles

Elenca i responsabili AGGIUNTIVI di una pratica (il responsabile principale è in matters.get): ciascuno è un collega (type "user", user_id impostato) o un gruppo di lavoro (type "workgroup", workgroup_id impostato), tutti in grado di vedere la pratica. Risponde 404 quando la pratica non è visibile.

Ambito
matters:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
type
string

"user" = un singolo collega; "workgroup" = ogni membro di un gruppo di lavoro.

Valori ammessi: "user" "workgroup"
user_id
integer | null

Id utente del collega per una voce "user" (lo passi come user_id a matters.responsibles.add); null per un gruppo di lavoro.

workgroup_id
integer | null

Id del gruppo di lavoro per una voce "workgroup"; null per un singolo collega. I responsabili dei gruppi di lavoro sono gestiti in Flowyer.

name
string | null

Nome visualizzato del collega o del gruppo di lavoro.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/responsibles?limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "type": "user",
      "user_id": 1234,
      "workgroup_id": 1234,
      "name": "string"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Aggiungi un responsabile della pratica

POST /api/agent/matters/{id}/responsibles

Aggiunge un collega (user_id da colleagues.list) come responsabile aggiuntivo di una pratica. Questo CONCEDE a quel collega l'accesso alla pratica, quindi aggiunga solo qualcuno che dovrebbe vederla; viene notificato. Idempotente: riaggiungere un responsabile esistente non comporta alcuna modifica.

Ambito
matters:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Pratica di cui il collega diventa responsabile (deve essere visibile).

Esempio: 1234

Corpo della richiesta application/json

user_idobbligatorio
integer>= 1

Collega da aggiungere: un id utente da colleagues.list. Aggiungerlo gli concede l'accesso alla pratica.

Esempio: 42

Risposte

200

OK.

dataobbligatorio
object
Campi di data
user_id
integer

Il collega ora responsabile della pratica.

name
string | null

Nome visualizzato del collega.

already_responsible
boolean

True quando il collega era già un responsabile della pratica (nulla è cambiato).

notified
boolean

True quando il collega è stato notificato di essere stato aggiunto. Mai true quando il collega è Lei, o quando era già responsabile.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/responsibles' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "user_id": 42
}'

Esempi di risposta

{
  "data": {
    "user_id": 1234,
    "name": "string",
    "already_responsible": true,
    "notified": true
  }
}

Clienti

Elenca i clienti

GET /api/agent/clients

Elenca i clienti dello studio (persone e aziende), in ordine alfabetico; q effettua la ricerca nel nome (accenti e maiuscole/minuscole ignorati), nell'e-mail e nel codice fiscale. Prima di creare un cliente, verifichi il nome con clients.resolve (tollera anche gli errori di battitura). I clienti archiviati sono nascosti a meno che include_archived non sia true.

Ambito
clients:read
Permesso Flowyer
contacts:read

Parametri di query

q
stringal massimo 100 caratteri

Ricerca nel nome (accenti e maiuscole/minuscole ignorati), nell'e-mail e nel codice fiscale.

Esempio: "Kovács"
is_person
boolean

true = solo persone fisiche, false = solo aziende.

include_archived
boolean
Predefinito: false
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/clients?q=Kov%C3%A1cs&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 512,
      "name": "Kovács Kft.",
      "is_person": true,
      "email": "info@example.hu",
      "phone": "string",
      "archived": true,
      "recorded_by_user_id": 1234,
      "recorded_by": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Risolvi il cliente per nome

GET /api/agent/clients/resolve

Trova un cliente a partire da un nome pronunciato o scritto in modo errato (accenti, maiuscole/minuscole e piccoli errori di battitura tollerati). Restituisce lo stato exact/similar/none e i clienti candidati. Solo "exact" è sicuro da usare direttamente; con "similar" o "none" chieda all'utente. Un nome con molti simili non è mai "exact": chieda un nome più completo.

Ambito
clients:read
Permesso Flowyer
contacts:read

Parametri di query

nameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Nome del cliente da cercare, così come ascoltato o dettato.

Esempio: "Józsi ingatlan"
limit
integer>= 1<= 10

Numero massimo di candidati da restituire (valore predefinito 5).

Predefinito: 5

Risposte

200

OK.

dataobbligatorio
object
Campi di data
status
string

exact = una corrispondenza certa (sicuro usarne l'id). similar = una o più corrispondenze approssimative, confermi prima con l'utente. none = nessuna corrispondenza, chieda all'utente.

Valori ammessi: "exact" "similar" "none"
matches
object[]

Clienti candidati, prima la corrispondenza migliore.

Campi di matches
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
total
integer

Quanti clienti hanno corrisposto prima che l'elenco fosse ridotto a limit.

truncated
boolean

True quando hanno corrisposto più clienti di quanti ne siano stati restituiti, oppure esistevano troppi nomi simili per verificarli tutti; chieda all'utente un nome più completo o aumenti limit anziché scegliere da un elenco incompleto.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/clients/resolve?name=J%C3%B3zsi%20ingatlan' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "status": "exact",
    "matches": [
      {
        "id": 512,
        "name": "Kovács Kft.",
        "is_person": true,
        "email": "info@example.hu",
        "phone": "string",
        "archived": true,
        "recorded_by_user_id": 1234,
        "recorded_by": "string",
        "created_at": "2026-10-30T09:15:00+01:00",
        "updated_at": "2026-10-30T09:15:00+01:00",
        "created_via_api": {
          "kind": "key",
          "key_id": 1234,
          "key_name": "string",
          "user_id": 1234,
          "user": "string",
          "at": "2026-10-30T09:15:00+01:00"
        }
      }
    ],
    "total": 1,
    "truncated": true
  }
}

Ottieni il cliente

GET /api/agent/clients/{id}

Restituisce un cliente con l'indirizzo e i dati di registrazione. I numeri dei documenti d'identità e le impostazioni delle tariffe non vengono mai restituiti.

Ambito
clients:read
Permesso Flowyer
contacts:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del cliente.

Esempio: 512

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
tax_number
string | null

Solo aziende; null per una persona fisica.

company_registration_number
string | null

Solo aziende; null per una persona fisica.

representative_name
string | null

Solo aziende; null per una persona fisica.

representative_position
string | null

Solo aziende; null per una persona fisica.

main_activity
string | null

Attività principale. Solo aziende; null per una persona fisica.

nationality_country
string | null
note
string | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/clients/512' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 512,
    "name": "Kovács Kft.",
    "is_person": true,
    "email": "info@example.hu",
    "phone": "string",
    "archived": true,
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "mailing_address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "tax_number": "string",
    "company_registration_number": "string",
    "representative_name": "string",
    "representative_position": "string",
    "main_activity": "string",
    "nationality_country": "string",
    "note": "string"
  }
}

Crea un cliente

POST /api/agent/clients

Crea un cliente (persona o azienda), registrato come creato dall'utente della chiave. Verifichi prima il nome con clients.resolve (tollera accenti mancanti ed errori di battitura): un 409 rileva solo un cliente attivo con lo stesso identico nome, a meno che allow_duplicate_name non sia true. I numeri di documento e le tariffe non possono essere impostati.

Ambito
clients:create
Permesso Flowyer
contacts:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

nameobbligatorio
stringalmeno 2 caratterial massimo 255 caratteri

Nome completo della persona o ragione sociale dell'azienda. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Kovács Kft."
is_person
boolean

true per una persona fisica, false (predefinito) per un'azienda.

Predefinito: false
email
string | nullal massimo 190 caratteri
Esempio: "info@kovacskft.hu"
phone
string | nullal massimo 64 caratteri
Esempio: "+36 1 234 5678"
address
object | null

Indirizzo della sede legale / di residenza.

Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object | null
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
tax_number
string | nullal massimo 64 caratteri

Codice fiscale dell'azienda (solo aziende).

Esempio: "12345678-2-41"
company_registration_number
string | nullal massimo 64 caratteri

Numero di registrazione dell'azienda (solo aziende).

Esempio: "01-09-123456"
representative_name
string | nullal massimo 255 caratteri

Solo aziende.

representative_position
string | nullal massimo 255 caratteri

Solo aziende.

main_activity
string | nullal massimo 255 caratteri

Attività principale (solo aziende).

nationality_country
string | nullal massimo 100 caratteri
note
string | nullal massimo 4000 caratteri
allow_duplicate_name
boolean

Crea anche se esiste un cliente attivo con lo stesso nome.

Predefinito: false
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
tax_number
string | null

Solo aziende; null per una persona fisica.

company_registration_number
string | null

Solo aziende; null per una persona fisica.

representative_name
string | null

Solo aziende; null per una persona fisica.

representative_position
string | null

Solo aziende; null per una persona fisica.

main_activity
string | null

Attività principale. Solo aziende; null per una persona fisica.

nationality_country
string | null
note
string | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
tax_number
string | null

Solo aziende; null per una persona fisica.

company_registration_number
string | null

Solo aziende; null per una persona fisica.

representative_name
string | null

Solo aziende; null per una persona fisica.

representative_position
string | null

Solo aziende; null per una persona fisica.

main_activity
string | null

Attività principale. Solo aziende; null per una persona fisica.

nationality_country
string | null
note
string | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Esiste un cliente attivo con lo stesso nome (client_exists, oppure client_exists_generic senza lo scope clients:read, quando il cliente esistente non può essere nominato; passi allow_duplicate_name per forzare), la Idempotency-Key è stata usata per un altro tipo di risorsa (idempotency_key_reused), oppure, senza una chiave, una richiesta identica è in elaborazione (duplicate_in_progress).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/clients' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "name": "Kovács Kft.",
  "email": "info@kovacskft.hu",
  "phone": "+36 1 234 5678",
  "tax_number": "12345678-2-41",
  "company_registration_number": "01-09-123456"
}'

Esempi di risposta

{
  "data": {
    "id": 512,
    "name": "Kovács Kft.",
    "is_person": true,
    "email": "info@example.hu",
    "phone": "string",
    "archived": true,
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "mailing_address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "tax_number": "string",
    "company_registration_number": "string",
    "representative_name": "string",
    "representative_position": "string",
    "main_activity": "string",
    "nationality_country": "string",
    "note": "string"
  },
  "created": true
}

Aggiorna il cliente

PATCH /api/agent/clients/{id}

Modifica i campi di contatto di un cliente (nome, email, telefono, indirizzo, nota, nazionalità e rappresentante/attività dell'azienda). I numeri di documento, i codici fiscali, le tariffe e il tipo persona/azienda non sono modificabili qui. Passi expected_updated_at; una modifica in conflitto risponde con 409.

Ambito
clients:update
Permesso Flowyer
contacts:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

name
string | nullalmeno 1 caratteri

Nome completo o ragione sociale. Testo semplice, al massimo 255 caratteri come NUOVO valore; non è possibile introdurre nemmeno "<" e ">", ma un nome memorizzato più lungo o che li contiene può essere restituito invariato. null mantiene il nome corrente.

email
string | nullal massimo 190 caratteri
phone
string | nullal massimo 64 caratteri
address
object | null

Indirizzo della sede legale / di residenza.

Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object | null
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
representative_name
string | nullal massimo 255 caratteri

Solo aziende.

representative_position
string | nullal massimo 255 caratteri

Solo aziende.

main_activity
string | nullal massimo 255 caratteri

Attività principale (solo aziende).

nationality_country
string | nullal massimo 100 caratteri
note
string | null

Nota a testo libero, al massimo 4000 caratteri come NUOVO valore; una nota memorizzata più lunga può essere restituita invariata. null cancella la nota.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id del cliente. Lo usi come client_id altrove.

Esempio: 512
name
string
Esempio: "Kovács Kft."
is_person
boolean

True per una persona fisica, false per un'azienda.

email
string | null
phone
string | null
archived
boolean
recorded_by_user_id
integer | null
recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Campi di address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
mailing_address
object
Campi di mailing_address
zip
string | nullal massimo 20 caratteri
city
string | nullal massimo 100 caratteri
street
string | nullal massimo 255 caratteri
tax_number
string | null

Solo aziende; null per una persona fisica.

company_registration_number
string | null

Solo aziende; null per una persona fisica.

representative_name
string | null

Solo aziende; null per una persona fisica.

representative_position
string | null

Solo aziende; null per una persona fisica.

main_activity
string | null

Attività principale. Solo aziende; null per una persona fisica.

nationality_country
string | null
note
string | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/clients/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "name": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 512,
    "name": "Kovács Kft.",
    "is_person": true,
    "email": "info@example.hu",
    "phone": "string",
    "archived": true,
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "mailing_address": {
      "zip": "string",
      "city": "string",
      "street": "string"
    },
    "tax_number": "string",
    "company_registration_number": "string",
    "representative_name": "string",
    "representative_position": "string",
    "main_activity": "string",
    "nationality_country": "string",
    "note": "string"
  },
  "updated": true
}

Attività

Elenca le attività

GET /api/agent/tasks

Elenca le attività (cose da fare con una scadenza) che l'utente può vedere, prima la scadenza più imminente. Attività aperte per impostazione predefinita; filtri per assegnatario, pratica, cliente o intervallo di scadenze.

Ambito
tasks:read
Permesso Flowyer
tasks:read

Parametri di query

status
string

open (predefinito), closed o all.

Valori ammessi: "open" "closed" "all"
Predefinito: "open"
assigned_to_user_id
integer>= 1

Solo le attività assegnate a questo utente (un id utente da colleagues.list).

matter_id
integer>= 1

Solo le attività di questa pratica.

client_id
integer>= 1

Solo le attività senza pratica di questo cliente.

deadline_from
string <date>

Scadenza a partire da questa data inclusa.

Esempio: "2026-11-01"
deadline_to
string <date>

Scadenza fino a questa data inclusa.

Esempio: "2026-11-30"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/tasks?deadline_from=2026-11-01&deadline_to=2026-11-30&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 9876,
      "subject": "Submit the statement of defence",
      "description": "string",
      "deadline": "2026-11-15",
      "priority": 2,
      "status": "open",
      "closed_at": "2026-10-30",
      "matter": {
        "id": 1234,
        "case_number": "string"
      },
      "client": {
        "id": 1234,
        "name": "string"
      },
      "assigned_to_user_id": 1234,
      "assigned_to": "string",
      "created_by_user_id": 1234,
      "created_by": "string",
      "flag_id": 1234,
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni l'attività

GET /api/agent/tasks/{id}

Restituisce un'attività. Risponde con 404 quando l'attività non esiste o l'utente non può vederla.

Ambito
tasks:read
Permesso Flowyer
tasks:read

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'attività.

Esempio: 9876

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/tasks/9876' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "subject": "Submit the statement of defence",
    "description": "string",
    "deadline": "2026-11-15",
    "priority": 2,
    "status": "open",
    "closed_at": "2026-10-30",
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "assigned_to_user_id": 1234,
    "assigned_to": "string",
    "created_by_user_id": 1234,
    "created_by": "string",
    "flag_id": 1234,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Crea un'attività

POST /api/agent/tasks

Crea un'attività (cosa da fare con una scadenza), su una pratica (matter_id, visibile e non archiviata) oppure senza pratica, facoltativamente per un cliente (client_id). L'assegnatario è per impostazione predefinita l'utente della chiave e viene notificato quando si tratta di qualcun altro.

Ambito
tasks:create
Permesso Flowyer
tasks:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

subjectobbligatorio
stringalmeno 2 caratterial massimo 1000 caratteri

Cosa deve essere fatto. Testo semplice.

Esempio: "Submit the statement of defence"
deadlineobbligatorio
string <date>

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
matter_id
integer | null>= 1

Pratica a cui appartiene l'attività. La ometta per un'attività senza pratica.

Esempio: 1234
client_id
integer | null>= 1

Cliente di un'attività senza pratica. Non consentito insieme a matter_id (un'attività di una pratica assume il cliente della pratica).

assigned_to_user_id
integer | null>= 1

Collega responsabile dell'attività: un id utente da colleagues.list (cerchi lì un nome dettato). Predefinito: l'utente della chiave.

priority
integer>= 1<= 3

1 = bassa, 2 = media (predefinito), 3 = alta.

Predefinito: 2
description
string | nullal massimo 10000 caratteri

Dettagli più estesi, testo semplice.

flag_id
integer | null>= 1

Id di un flag di attività dello studio (etichetta).

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/tasks' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "subject": "Submit the statement of defence",
  "deadline": "2026-11-15",
  "matter_id": 1234
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "subject": "Submit the statement of defence",
    "description": "string",
    "deadline": "2026-11-15",
    "priority": 2,
    "status": "open",
    "closed_at": "2026-10-30",
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "assigned_to_user_id": 1234,
    "assigned_to": "string",
    "created_by_user_id": 1234,
    "created_by": "string",
    "flag_id": 1234,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna l'attività

PATCH /api/agent/tasks/{id}

Modifica un'attività: oggetto, scadenza, descrizione, priorità, flag, assegnatario o la pratica a cui appartiene. Spostarla su una pratica ricalcola il collegamento al tribunale e rimuove un cliente diretto; client_id è solo per un'attività senza pratica. Passi expected_updated_at; una modifica in conflitto risponde con 409.

Ambito
tasks:update
Permesso Flowyer
tasks:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

subject
string | nullalmeno 1 caratteri

Cosa deve essere fatto. Testo semplice, al massimo 1000 caratteri come NUOVO valore; un oggetto memorizzato più lungo può essere restituito invariato. null mantiene l'oggetto corrente.

deadline
string <date> | null

Data di scadenza, YYYY-MM-DD. null mantiene la scadenza corrente (una scadenza non può essere cancellata).

matter_id
integer | null>= 1

Sposta l'attività su questa pratica (deve essere visibile e non archiviata), oppure null per scollegarla. Inviare la pratica corrente dell'attività non cambia nulla.

client_id
integer | null>= 1

Cliente di un'attività senza pratica. Consentito solo quando l'attività non ha una pratica.

assigned_to_user_id
integer | null>= 0

Nuovo assegnatario: l'id utente di un collega attivo da colleagues.list. Viene notificato quando non è Lei. Inviare quello corrente, o null / 0 con cui viene restituita un'attività senza assegnatario, non cambia nulla.

priority
integer>= 1<= 3

1 = bassa, 2 = media, 3 = alta. La ometta per mantenere la priorità corrente (anche quando l'attività viene restituita con priorità null); null viene rifiutato.

description
string | null

Dettagli più estesi, testo semplice, al massimo 10000 caratteri come NUOVO valore; una descrizione memorizzata più lunga può essere restituita invariata.

flag_id
integer | null>= 1

Id di un flag di attività dello studio (etichetta), oppure null per cancellarlo.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/tasks/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "subject": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "subject": "Submit the statement of defence",
    "description": "string",
    "deadline": "2026-11-15",
    "priority": 2,
    "status": "open",
    "closed_at": "2026-10-30",
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "assigned_to_user_id": 1234,
    "assigned_to": "string",
    "created_by_user_id": 1234,
    "created_by": "string",
    "flag_id": 1234,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Chiudi l'attività

POST /api/agent/tasks/{id}/close

Chiude un'attività. Se vengono forniti i minuti, registra anche una voce di tempo (richiede workhours:create e una pratica: quella propria dell'attività, oppure matter_id su un'attività senza pratica); i minuti fatturabili vengono limitati al tetto orario dello studio. Una seconda chiusura risponde con 409, quindi un nuovo tentativo non registra mai una seconda voce.

Ambito
tasks:update
Permesso Flowyer
tasks:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'attività.

Esempio: 9876

Corpo della richiesta application/json

minutes_spent
integer | null>= 0<= 100000

Tempo impiegato, in minuti. Registrare qualsiasi tempo richiede lo scope workhours:create e una pratica.

minutes_invoiceable
integer | null>= 0<= 100000

Minuti fatturabili; limitati al tetto orario dello studio.

minutes_normative
integer | null>= 0<= 100000

Minuti normativi; memorizzati grezzi, mai limitati.

matter_id
integer | null>= 1

Assegna questa pratica a un'attività SENZA PRATICA alla chiusura (e rende così possibile registrare il tempo). Non consentito quando l'attività ha già una pratica.

client_id
integer | null>= 1

Cliente diretto (Megbízó) per un'attività senza pratica chiusa senza una pratica.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
subject
string
Esempio: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data di scadenza, YYYY-MM-DD.

Esempio: "2026-11-15"
priority
integer | null

1 = bassa, 2 = media, 3 = alta; null = non impostata (un'attività più vecchia senza priorità).

Esempio: 2
status
string
Valori ammessi: "open" "closed"
closed_at
string <date> | null

Giorno in cui l'attività è stata chiusa, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

matter
object | null

La pratica a cui appartiene l'attività, se presente.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente: il primo cliente della pratica, oppure il cliente proprio dell'attività quando non ha una pratica.

Campi di client
id
integer
name
string
assigned_to_user_id
integer | null
assigned_to
string | null
created_by_user_id
integer | null
created_by
string | null
flag_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created_via_api
object | null
Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
booked_workhour
object | null

La voce di tempo registrata dalla chiusura, oppure null quando non è stato inserito alcun tempo.

Campi di booked_workhour
id
integer>= 1
minutes
integer
minutes_invoiceable
integer
minutes_normative
integer
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/tasks/9876/close' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "subject": "Submit the statement of defence",
    "description": "string",
    "deadline": "2026-11-15",
    "priority": 2,
    "status": "open",
    "closed_at": "2026-10-30",
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "assigned_to_user_id": 1234,
    "assigned_to": "string",
    "created_by_user_id": 1234,
    "created_by": "string",
    "flag_id": 1234,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "booked_workhour": {
      "id": 1234,
      "minutes": 0,
      "minutes_invoiceable": 0,
      "minutes_normative": 0
    }
  }
}

Ore di lavoro

Elenca le voci di tempo

GET /api/agent/workhours

Elenca le voci di tempo attive (non ancora fatturate) sulle pratiche che l'utente può vedere, prima le più recenti. Filtra per pratica, collega responsabile o intervallo di date. Anche le voci escluse dal riepilogo vengono elencate, contrassegnate con excluded: true; le escluda dai totali fatturabili.

Ambito
workhours:read
Permesso Flowyer
workhours:read

Parametri di query

matter_id
integer>= 1

Solo le voci di questa pratica.

Esempio: 1234
responsible_user_id
integer>= 1

Solo le voci registrate a questo collega (un id utente da colleagues.list).

date_from
string <date>

Solo le voci a partire da questa data inclusa (YYYY-MM-DD).

date_to
string <date>

Solo le voci fino a questa data inclusa (YYYY-MM-DD).

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id della voce di tempo.

matter_id
integer | null

Pratica a cui è registrata la voce.

date
string <date> | null
activity
string | null

Cosa è stato fatto (testo semplice).

minutes
integer | null

Minuti impiegati.

minutes_invoiceable
integer | null

Minuti fatturabili dopo l'applicazione del tetto orario dello studio (possono essere inferiori a quelli richiesti). Contano ai fini della fatturazione solo finché excluded è false.

minutes_normative
integer | null

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null

Collega a cui è registrato il tempo.

responsible
string | null
recorded_by_user_id
integer | null

Chi ha registrato la voce.

locked
boolean

True quando la voce è bloccata (di sola lettura tramite l'API).

excluded
boolean

True quando un collega ha escluso la voce dal riepilogo della pratica: non viene fatturata e i suoi minuti sono esclusi dai totali fatturabili.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/workhours?matter_id=1234&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "matter_id": 1234,
      "date": "2026-10-30",
      "activity": "string",
      "minutes": 0,
      "minutes_invoiceable": 0,
      "minutes_normative": 0,
      "responsible_user_id": 1234,
      "responsible": "string",
      "recorded_by_user_id": 1234,
      "locked": true,
      "excluded": true,
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni la voce di tempo

GET /api/agent/workhours/{id}

Restituisce una voce di tempo attiva per id, se la relativa pratica è visibile all'utente.

Ambito
workhours:read
Permesso Flowyer
workhours:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della voce di tempo.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id della voce di tempo.

matter_id
integer | null

Pratica a cui è registrata la voce.

date
string <date> | null
activity
string | null

Cosa è stato fatto (testo semplice).

minutes
integer | null

Minuti impiegati.

minutes_invoiceable
integer | null

Minuti fatturabili dopo l'applicazione del tetto orario dello studio (possono essere inferiori a quelli richiesti). Contano ai fini della fatturazione solo finché excluded è false.

minutes_normative
integer | null

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null

Collega a cui è registrato il tempo.

responsible
string | null
recorded_by_user_id
integer | null

Chi ha registrato la voce.

locked
boolean

True quando la voce è bloccata (di sola lettura tramite l'API).

excluded
boolean

True quando un collega ha escluso la voce dal riepilogo della pratica: non viene fatturata e i suoi minuti sono esclusi dai totali fatturabili.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/workhours/1234' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "minutes": 0,
    "minutes_invoiceable": 0,
    "minutes_normative": 0,
    "responsible_user_id": 1234,
    "responsible": "string",
    "recorded_by_user_id": 1234,
    "locked": true,
    "excluded": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  }
}

Registra una voce di tempo

POST /api/agent/workhours

Registra una voce di tempo su una pratica: data, attività, minuti impiegati e minuti fatturabili. Minuti fatturabili omessi significano non fatturabile: invii minutes_invoiceable per il lavoro fatturabile. Vengono limitati al tetto orario dello studio. Il collega responsabile è per impostazione predefinita l'utente della chiave e, in caso contrario, viene notificato.

Ambito
workhours:create
Permesso Flowyer
workhours:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

matter_idobbligatorio
integer>= 1

Pratica a cui è registrato il tempo (deve essere visibile).

Esempio: 1234
dateobbligatorio
string <date>

Data del lavoro, YYYY-MM-DD.

Esempio: "2026-10-30"
subject
stringalmeno 2 caratterial massimo 1000 caratteri

Cosa è stato fatto; il lato di lettura la restituisce come activity e qui è accettato uno dei due nomi (uno dei due è obbligatorio). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Drafting the statement of claim"
activity
stringalmeno 2 caratterial massimo 1000 caratteri

Lo stesso campo di subject, con il nome usato dal lato di lettura. Ne invii uno dei due.

Modello: ^[^<>]*$
minutes
integer | null>= 0<= 100000

Minuti effettivamente impiegati.

Esempio: 90
minutes_invoiceable
integer | null>= 0<= 100000

Minuti fatturabili richiesti. Omessi o null = non fatturabile (la voce non fattura nulla; non vengono derivati da minutes): per il lavoro fatturabile li invii esplicitamente, di solito uguali a minutes. Il tetto orario dello studio può ridurre il valore memorizzato. Contano ai fini della fatturazione solo finché la voce non è esclusa dal riepilogo.

Esempio: 60
minutes_normative
integer | null>= 0<= 100000

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null>= 1

Collega a cui è registrato il tempo: un id utente da colleagues.list (cerchi lì un nome dettato). Predefinito: l'utente della chiave.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce di tempo.

matter_id
integer | null

Pratica a cui è registrata la voce.

date
string <date> | null
activity
string | null

Cosa è stato fatto (testo semplice).

minutes
integer | null

Minuti impiegati.

minutes_invoiceable
integer | null

Minuti fatturabili dopo l'applicazione del tetto orario dello studio (possono essere inferiori a quelli richiesti). Contano ai fini della fatturazione solo finché excluded è false.

minutes_normative
integer | null

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null

Collega a cui è registrato il tempo.

responsible
string | null
recorded_by_user_id
integer | null

Chi ha registrato la voce.

locked
boolean

True quando la voce è bloccata (di sola lettura tramite l'API).

excluded
boolean

True quando un collega ha escluso la voce dal riepilogo della pratica: non viene fatturata e i suoi minuti sono esclusi dai totali fatturabili.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce di tempo.

matter_id
integer | null

Pratica a cui è registrata la voce.

date
string <date> | null
activity
string | null

Cosa è stato fatto (testo semplice).

minutes
integer | null

Minuti impiegati.

minutes_invoiceable
integer | null

Minuti fatturabili dopo l'applicazione del tetto orario dello studio (possono essere inferiori a quelli richiesti). Contano ai fini della fatturazione solo finché excluded è false.

minutes_normative
integer | null

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null

Collega a cui è registrato il tempo.

responsible
string | null
recorded_by_user_id
integer | null

Chi ha registrato la voce.

locked
boolean

True quando la voce è bloccata (di sola lettura tramite l'API).

excluded
boolean

True quando un collega ha escluso la voce dal riepilogo della pratica: non viene fatturata e i suoi minuti sono esclusi dai totali fatturabili.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/workhours' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "matter_id": 1234,
  "date": "2026-10-30",
  "subject": "Drafting the statement of claim",
  "minutes": 90,
  "minutes_invoiceable": 60
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "minutes": 0,
    "minutes_invoiceable": 0,
    "minutes_normative": 0,
    "responsible_user_id": 1234,
    "responsible": "string",
    "recorded_by_user_id": 1234,
    "locked": true,
    "excluded": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Aggiorna la voce di tempo

PATCH /api/agent/workhours/{id}

Modifica una voce di tempo attiva: data, attività (subject o activity), minuti, minuti fatturabili (un numero modificato viene limitato al tetto orario, uno rinviato invariato viene mantenuto) e il collega responsabile. Una voce bloccata o fatturata non può essere modificata (409). Passi expected_updated_at; un conflitto risponde con 409.

Ambito
workhours:update
Permesso Flowyer
workhours:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

date
string <date> | null

Data del lavoro, YYYY-MM-DD. null mantiene la data corrente.

subject
string | nullalmeno 1 caratteri

Cosa è stato fatto, il valore che il lato di lettura restituisce come activity (è accettato uno dei due nomi; null sotto uno di essi significa "non fornito", vengono rifiutati solo due testi diversi). Testo semplice, al massimo 1000 caratteri come NUOVO valore; non è possibile introdurre nemmeno "<" e ">", ma un testo memorizzato più lungo o che li contiene può essere restituito invariato. null mantiene il testo corrente.

activity
string | nullalmeno 1 caratteri

Lo stesso campo di subject, con il nome usato dal lato di lettura. Ne invii uno dei due (null sotto l'altro va bene).

minutes
integer | null>= 0<= 100000

Minuti effettivamente impiegati; null li cancella.

minutes_invoiceable
integer | null>= 0<= 100000

Minuti fatturabili richiesti. Un numero diverso da quello memorizzato viene limitato a ciò che resta del tetto orario; rinviare il valore restituito dalla lettura lo mantiene come registrato (non viene limitato di nuovo). null li cancella. Contano ai fini della fatturazione solo finché la voce non è esclusa dal riepilogo (excluded è false).

minutes_normative
integer | null>= 0<= 100000

Minuti normativi (mai limitati); null li cancella.

responsible_user_id
integer | null>= 0

Nuovo collega responsabile: l'id utente di un collega attivo da colleagues.list; viene notificato quando non è Lei. Inviare quello corrente, o null / 0 con cui viene restituita una voce senza responsabile, non cambia nulla.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce di tempo.

matter_id
integer | null

Pratica a cui è registrata la voce.

date
string <date> | null
activity
string | null

Cosa è stato fatto (testo semplice).

minutes
integer | null

Minuti impiegati.

minutes_invoiceable
integer | null

Minuti fatturabili dopo l'applicazione del tetto orario dello studio (possono essere inferiori a quelli richiesti). Contano ai fini della fatturazione solo finché excluded è false.

minutes_normative
integer | null

Minuti normativi (informativi; mai limitati).

responsible_user_id
integer | null

Collega a cui è registrato il tempo.

responsible
string | null
recorded_by_user_id
integer | null

Chi ha registrato la voce.

locked
boolean

True quando la voce è bloccata (di sola lettura tramite l'API).

excluded
boolean

True quando un collega ha escluso la voce dal riepilogo della pratica: non viene fatturata e i suoi minuti sono esclusi dai totali fatturabili.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at), oppure è stato fatturato / bloccato e non può più essere modificato tramite l'API (record_locked; effettui la modifica in Flowyer).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/workhours/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "date": "2026-10-30"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "minutes": 0,
    "minutes_invoiceable": 0,
    "minutes_normative": 0,
    "responsible_user_id": 1234,
    "responsible": "string",
    "recorded_by_user_id": 1234,
    "locked": true,
    "excluded": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Costi

Elenca i costi

GET /api/agent/costs

Elenca i costi attivi delle pratiche che l'utente può vedere, prima i più recenti (un costo fatturato non è più presente qui). Filtra per pratica, collega responsabile o intervallo di date. Gli importi sono al netto. Le righe contrassegnate con excluded: true sono fuori dal riepilogo e le righe contrassegnate con locked: true sono gestite da Flowyer.

Ambito
costs:read
Permesso Flowyer
cases:read, summary:read

Parametri di query

matter_id
integer>= 1

Solo i costi di questa pratica.

Esempio: 1234
responsible_user_id
integer>= 1

Solo i costi registrati per questo collega (un id utente da colleagues.list).

date_from
string <date>

Solo i costi a partire da questa data inclusa (YYYY-MM-DD).

date_to
string <date>

Solo i costi fino a questa data inclusa (YYYY-MM-DD).

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id del costo.

matter_id
integer | null

Pratica a cui appartiene il costo.

date
string <date> | null
activity
string | null

Descrizione del costo (testo semplice).

cost
number | null

Importo netto del costo (IVA esclusa).

cost_invoiceable
number | null

Importo netto da addebitare al cliente. Conta ai fini della fatturazione solo finché excluded è false.

currency_id
integer | null

Id della valuta (elenco valute di Flowyer).

currency
string | null

Codice ISO della valuta, ad es. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True quando un collega ha escluso il costo dal riepilogo della pratica: non viene fatturato ed è escluso dai totali fatturabili.

locked
boolean

True quando il costo è gestito da Flowyer, replicato da una fattura in entrata o da una maggiorazione di esborso, e non può essere modificato tramite l'API (costs.update risponde con 409 record_locked, details.reason indica quale).

approved_for_billing
boolean

True quando un collega ha approvato il costo per la fatturazione nel riepilogo della pratica. Rimane modificabile tramite l'API (come nel web) e l'approvazione NON viene richiesta di nuovo in seguito: lo segnali prima di modificare l'importo di un costo approvato.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/costs?matter_id=1234&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "matter_id": 1234,
      "date": "2026-10-30",
      "activity": "string",
      "cost": 0,
      "cost_invoiceable": 0,
      "currency_id": 1234,
      "currency": "string",
      "responsible_user_id": 1234,
      "responsible": "string",
      "excluded": true,
      "locked": true,
      "approved_for_billing": true,
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni il costo

GET /api/agent/costs/{id}

Restituisce un costo attivo per id, se la relativa pratica è visibile all'utente. Gli importi sono al netto.

Ambito
costs:read
Permesso Flowyer
cases:read, summary:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del costo.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id del costo.

matter_id
integer | null

Pratica a cui appartiene il costo.

date
string <date> | null
activity
string | null

Descrizione del costo (testo semplice).

cost
number | null

Importo netto del costo (IVA esclusa).

cost_invoiceable
number | null

Importo netto da addebitare al cliente. Conta ai fini della fatturazione solo finché excluded è false.

currency_id
integer | null

Id della valuta (elenco valute di Flowyer).

currency
string | null

Codice ISO della valuta, ad es. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True quando un collega ha escluso il costo dal riepilogo della pratica: non viene fatturato ed è escluso dai totali fatturabili.

locked
boolean

True quando il costo è gestito da Flowyer, replicato da una fattura in entrata o da una maggiorazione di esborso, e non può essere modificato tramite l'API (costs.update risponde con 409 record_locked, details.reason indica quale).

approved_for_billing
boolean

True quando un collega ha approvato il costo per la fatturazione nel riepilogo della pratica. Rimane modificabile tramite l'API (come nel web) e l'approvazione NON viene richiesta di nuovo in seguito: lo segnali prima di modificare l'importo di un costo approvato.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/costs/1234' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "cost": 0,
    "cost_invoiceable": 0,
    "currency_id": 1234,
    "currency": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "excluded": true,
    "locked": true,
    "approved_for_billing": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  }
}

Registra un costo

POST /api/agent/costs

Registra un costo (esborso) su una pratica: data, testo (subject, restituito come activity), importo netto, importo netto addebitato al cliente e valuta (predefinito: la valuta dello studio). Gli importi sono al netto (IVA esclusa). Il collega responsabile è per impostazione predefinita l'utente della chiave e, in caso contrario, viene notificato.

Ambito
costs:create
Permesso Flowyer
cases:create, summary:read

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

matter_idobbligatorio
integer>= 1

Pratica a cui appartiene il costo (deve essere visibile).

Esempio: 1234
dateobbligatorio
string <date>

Data del costo, YYYY-MM-DD.

Esempio: "2026-10-30"
subject
stringalmeno 2 caratterial massimo 1000 caratteri

Descrizione del costo; il lato di lettura la restituisce come activity e qui è accettato uno dei due nomi (uno dei due è obbligatorio). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Court filing fee"
activity
stringalmeno 2 caratterial massimo 1000 caratteri

Lo stesso campo di subject, con il nome usato dal lato di lettura. Ne invii uno dei due.

Modello: ^[^<>]*$
costobbligatorio
integer>= 0<= 2147483647

Importo netto del costo (IVA esclusa), un numero intero nell'unità principale della valuta (i centesimi non vengono memorizzati).

Esempio: 15000
cost_invoiceable
integer | null>= 0<= 2147483647

Importo netto da addebitare al cliente, un numero intero (lo ometta se non addebitato). Conta ai fini della fatturazione solo finché il costo non è escluso dal riepilogo.

Esempio: 15000
currency_id
integer | null>= 1

Id della valuta dall'elenco valute di Flowyer (non un codice ISO). Lo ometta per usare la valuta dello studio (GET /me office.currency_id / office.currency); un id sconosciuto risponde con 422 e gli id e i codici accettati in details.allowed.

responsible_user_id
integer | null>= 1

Collega responsabile: un id utente da colleagues.list (cerchi lì un nome dettato). Predefinito: l'utente della chiave.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id del costo.

matter_id
integer | null

Pratica a cui appartiene il costo.

date
string <date> | null
activity
string | null

Descrizione del costo (testo semplice).

cost
number | null

Importo netto del costo (IVA esclusa).

cost_invoiceable
number | null

Importo netto da addebitare al cliente. Conta ai fini della fatturazione solo finché excluded è false.

currency_id
integer | null

Id della valuta (elenco valute di Flowyer).

currency
string | null

Codice ISO della valuta, ad es. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True quando un collega ha escluso il costo dal riepilogo della pratica: non viene fatturato ed è escluso dai totali fatturabili.

locked
boolean

True quando il costo è gestito da Flowyer, replicato da una fattura in entrata o da una maggiorazione di esborso, e non può essere modificato tramite l'API (costs.update risponde con 409 record_locked, details.reason indica quale).

approved_for_billing
boolean

True quando un collega ha approvato il costo per la fatturazione nel riepilogo della pratica. Rimane modificabile tramite l'API (come nel web) e l'approvazione NON viene richiesta di nuovo in seguito: lo segnali prima di modificare l'importo di un costo approvato.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id del costo.

matter_id
integer | null

Pratica a cui appartiene il costo.

date
string <date> | null
activity
string | null

Descrizione del costo (testo semplice).

cost
number | null

Importo netto del costo (IVA esclusa).

cost_invoiceable
number | null

Importo netto da addebitare al cliente. Conta ai fini della fatturazione solo finché excluded è false.

currency_id
integer | null

Id della valuta (elenco valute di Flowyer).

currency
string | null

Codice ISO della valuta, ad es. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True quando un collega ha escluso il costo dal riepilogo della pratica: non viene fatturato ed è escluso dai totali fatturabili.

locked
boolean

True quando il costo è gestito da Flowyer, replicato da una fattura in entrata o da una maggiorazione di esborso, e non può essere modificato tramite l'API (costs.update risponde con 409 record_locked, details.reason indica quale).

approved_for_billing
boolean

True quando un collega ha approvato il costo per la fatturazione nel riepilogo della pratica. Rimane modificabile tramite l'API (come nel web) e l'approvazione NON viene richiesta di nuovo in seguito: lo segnali prima di modificare l'importo di un costo approvato.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/costs' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "matter_id": 1234,
  "date": "2026-10-30",
  "subject": "Court filing fee",
  "cost": 15000,
  "cost_invoiceable": 15000
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "cost": 0,
    "cost_invoiceable": 0,
    "currency_id": 1234,
    "currency": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "excluded": true,
    "locked": true,
    "approved_for_billing": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Aggiorna il costo

PATCH /api/agent/costs/{id}

Modifica un costo attivo: testo (subject, restituito come activity), data, importi netti, valuta e collega responsabile. Un costo contrassegnato con locked: true non può essere modificato (409 record_locked, details.reason). Passi expected_updated_at; una modifica in conflitto risponde con 409.

Ambito
costs:update
Permesso Flowyer
cases:modify, summary:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

date
string <date> | null

Data del costo, YYYY-MM-DD. null mantiene la data corrente.

subject
string | nullalmeno 1 caratteri

Descrizione del costo, il valore che il lato di lettura restituisce come activity (è accettato uno dei due nomi; null sotto uno di essi significa "non fornito", vengono rifiutati solo due testi diversi). Testo semplice, al massimo 1000 caratteri come NUOVO valore; non è possibile introdurre nemmeno "<" e ">", ma un testo memorizzato più lungo o che li contiene può essere restituito invariato. null mantiene il testo corrente.

activity
string | nullalmeno 1 caratteri

Lo stesso campo di subject, con il nome usato dal lato di lettura. Ne invii uno dei due (null sotto l'altro va bene).

cost
integer | null>= 0<= 2147483647

Importo netto del costo (IVA esclusa), un numero intero nell'unità principale della valuta (i centesimi non vengono memorizzati). null cancella l'importo.

cost_invoiceable
integer | null>= 0<= 2147483647

Importo netto da addebitare al cliente, un numero intero; null lo cancella. Conta ai fini della fatturazione solo finché il costo non è escluso dal riepilogo (excluded è false).

currency_id
integer | null>= 0

Id della valuta dall'elenco valute di Flowyer (non un codice ISO; la valuta dello studio è GET /me office.currency_id). Un id sconosciuto risponde con 422 e gli id e i codici accettati in details.allowed. null, o lo 0 con cui viene restituito un costo legacy non impostato, mantiene la valuta corrente.

responsible_user_id
integer | null>= 0

Nuovo collega responsabile: l'id utente di un collega attivo da colleagues.list. Inviare quello corrente, o null / 0 con cui viene restituito un costo senza responsabile, non cambia nulla.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id del costo.

matter_id
integer | null

Pratica a cui appartiene il costo.

date
string <date> | null
activity
string | null

Descrizione del costo (testo semplice).

cost
number | null

Importo netto del costo (IVA esclusa).

cost_invoiceable
number | null

Importo netto da addebitare al cliente. Conta ai fini della fatturazione solo finché excluded è false.

currency_id
integer | null

Id della valuta (elenco valute di Flowyer).

currency
string | null

Codice ISO della valuta, ad es. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True quando un collega ha escluso il costo dal riepilogo della pratica: non viene fatturato ed è escluso dai totali fatturabili.

locked
boolean

True quando il costo è gestito da Flowyer, replicato da una fattura in entrata o da una maggiorazione di esborso, e non può essere modificato tramite l'API (costs.update risponde con 409 record_locked, details.reason indica quale).

approved_for_billing
boolean

True quando un collega ha approvato il costo per la fatturazione nel riepilogo della pratica. Rimane modificabile tramite l'API (come nel web) e l'approvazione NON viene richiesta di nuovo in seguito: lo segnali prima di modificare l'importo di un costo approvato.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Rinvii questo valore come expected_updated_at durante l'aggiornamento.

updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at), oppure è stato fatturato / bloccato e non può più essere modificato tramite l'API (record_locked; effettui la modifica in Flowyer).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/costs/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "date": "2026-10-30"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter_id": 1234,
    "date": "2026-10-30",
    "activity": "string",
    "cost": 0,
    "cost_invoiceable": 0,
    "currency_id": 1234,
    "currency": "string",
    "responsible_user_id": 1234,
    "responsible": "string",
    "excluded": true,
    "locked": true,
    "approved_for_billing": true,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Fatture

Elenca le fatture

GET /api/agent/invoices

Elenca le fatture (emesse e ricevute), prima la data di emissione più recente. direction=outgoing è l'elenco delle fatture emesse dallo studio ed esclude le proforma (direction=proforma le elenca). Di sola lettura: le fatture non possono essere create o modificate tramite l'API. Le fatture di pratiche che l'utente non può vedere sono nascoste.

Ambito
invoices:read
Permesso Flowyer
invoices:read, summary:read

Parametri di query

direction
string

I tre elenchi propri dello studio: outgoing = fatture emesse dallo studio, proforma escluse (una riga legacy senza tipo di documento conta come fattura, come nella dashboard dello studio); proforma = richieste di pagamento (díjbekérő) emesse dallo studio; incoming = ricevute.

Valori ammessi: "incoming" "outgoing" "proforma"
paid_status
string
Valori ammessi: "unpaid" "paid" "partially_paid" "cancelled"
client_id
integer>= 1
matter_id
integer>= 1
issued_from
string <date>

Data di emissione a partire da questa data inclusa.

Esempio: "2026-01-01"
issued_to
string <date>

Data di emissione fino a questa data inclusa.

Esempio: "2026-12-31"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 301
invoice_number
string | null
Esempio: "FLW-2026-0042"
direction
string | null

outgoing = emesse dallo studio, incoming = ricevute dallo studio.

Valori ammessi: "incoming" "outgoing"
document_type
string | null

"proforma" è una richiesta di pagamento, non una fattura emessa: non è un ricavo e non deve essere conteggiata con quelle emesse. invoices.list direction=outgoing esclude le proforma, direction=proforma le elenca. Null su una riga legacy, che conta come fattura.

Valori ammessi: "invoice" "proforma" "receipt"
source
string | null
Valori ammessi: "manual" "szamlazz_outgoing" "szamlazz_imported"
paid_status
string | null
Valori ammessi: "unpaid" "paid" "partially_paid" "cancelled"
issued_date
string <date> | null
due_date
string <date> | null
paid_date
string <date> | null
completion_date
string <date> | null
net_amount
number | null
gross_amount
number | null
currency
string | null
Esempio: "HUF"
payment_method_id
integer | null
payment_method
string | null

Nome localizzato del metodo di pagamento (ad es. bonifico bancario); in inglese quando la lingua dello studio non ne ha una traduzione, null quando il metodo non ha alcun nome. Identifichi il metodo tramite payment_method_id.

supplier
string | null

Emittente di una fattura in entrata.

client
object | null
Campi di client
id
integer
name
string
matter_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/invoices?issued_from=2026-01-01&issued_to=2026-12-31&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 301,
      "invoice_number": "FLW-2026-0042",
      "direction": "incoming",
      "document_type": "invoice",
      "source": "manual",
      "paid_status": "unpaid",
      "issued_date": "2026-10-30",
      "due_date": "2026-10-30",
      "paid_date": "2026-10-30",
      "completion_date": "2026-10-30",
      "net_amount": 0,
      "gross_amount": 0,
      "currency": "HUF",
      "payment_method_id": 1234,
      "payment_method": "string",
      "supplier": "string",
      "client": {
        "id": 1234,
        "name": "string"
      },
      "matter_id": 1234,
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni la fattura

GET /api/agent/invoices/{id}

Restituisce una fattura. Di sola lettura. Risponde con 404 quando non esiste o appartiene a una pratica che l'utente non può vedere.

Ambito
invoices:read
Permesso Flowyer
invoices:read, summary:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della fattura.

Esempio: 301

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 301
invoice_number
string | null
Esempio: "FLW-2026-0042"
direction
string | null

outgoing = emesse dallo studio, incoming = ricevute dallo studio.

Valori ammessi: "incoming" "outgoing"
document_type
string | null

"proforma" è una richiesta di pagamento, non una fattura emessa: non è un ricavo e non deve essere conteggiata con quelle emesse. invoices.list direction=outgoing esclude le proforma, direction=proforma le elenca. Null su una riga legacy, che conta come fattura.

Valori ammessi: "invoice" "proforma" "receipt"
source
string | null
Valori ammessi: "manual" "szamlazz_outgoing" "szamlazz_imported"
paid_status
string | null
Valori ammessi: "unpaid" "paid" "partially_paid" "cancelled"
issued_date
string <date> | null
due_date
string <date> | null
paid_date
string <date> | null
completion_date
string <date> | null
net_amount
number | null
gross_amount
number | null
currency
string | null
Esempio: "HUF"
payment_method_id
integer | null
payment_method
string | null

Nome localizzato del metodo di pagamento (ad es. bonifico bancario); in inglese quando la lingua dello studio non ne ha una traduzione, null quando il metodo non ha alcun nome. Identifichi il metodo tramite payment_method_id.

supplier
string | null

Emittente di una fattura in entrata.

client
object | null
Campi di client
id
integer
name
string
matter_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
notes
string | null
received_date
string <date> | null
sent_date
string <date> | null
proforma_invoice_id
integer | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/invoices/301' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 301,
    "invoice_number": "FLW-2026-0042",
    "direction": "incoming",
    "document_type": "invoice",
    "source": "manual",
    "paid_status": "unpaid",
    "issued_date": "2026-10-30",
    "due_date": "2026-10-30",
    "paid_date": "2026-10-30",
    "completion_date": "2026-10-30",
    "net_amount": 0,
    "gross_amount": 0,
    "currency": "HUF",
    "payment_method_id": 1234,
    "payment_method": "string",
    "supplier": "string",
    "client": {
      "id": 1234,
      "name": "string"
    },
    "matter_id": 1234,
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "notes": "string",
    "received_date": "2026-10-30",
    "sent_date": "2026-10-30",
    "proforma_invoice_id": 1234
  }
}

Documenti

Elenca i documenti della pratica

GET /api/agent/matters/{id}/documents

Elenca le versioni correnti dei documenti archiviati sotto una pratica: nomi, dimensioni, cartelle e chi li ha caricati. Solo metadati; usi documents.download (scope documents:download) per un link firmato al contenuto. I documenti con nome vengono prima, in ordine alfabetico, poi quelli importati che non hanno nome.

Ambito
documents:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

q
stringal massimo 100 caratteri

Filtra per nome del file.

Esempio: "contract"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
name
string

Nome del file come mostrato in Flowyer: il nome memorizzato con il documento, oppure il suo nome di archiviazione quando è stato importato da un sistema più vecchio senza nome. documents.list è ordinato per nome memorizzato: i documenti che ne hanno uno vengono prima, in ordine alfabetico, poi quelli importati senza nome memorizzato, dal più vecchio (l'ordine in cui sono stati archiviati in Flowyer), che pertanto non sono ordinati per il nome qui mostrato. L'ordine è lo stesso in ogni pagina, quindi limit e offset scorrono l'elenco senza ripetizioni né lacune.

Esempio: "Contract_v2.docx"
size
integer | null

Byte.

version
integer

Numero di versione corrente del file.

folder
object | null

La cartella in cui è archiviato il documento, oppure null alla radice della pratica. documents.upload.complete risponde null quando la cartella scelta in documents.upload.init è stata eliminata mentre i byte venivano caricati: il documento viene allora archiviato alla radice della pratica, dove Flowyer lo mostra. Se la radice contiene già un documento con quel nome, il caricamento viene archiviato con un nome con suffisso ("Contract_2.pdf") invece di diventare una nuova versione di quel documento non correlato; il 201 restituisce il name memorizzato.

Campi di folder
id
integer
name
string
path
string

Percorso della cartella all'interno della pratica, separato da "/".

folder_deleted
boolean

True quando il documento è archiviato in una cartella che non esiste più, che l'elenco file di Flowyer non mostra (folder è null per esso, come per un documento alla radice della pratica). documents.upload.complete risponde true solo se la cartella è stata eliminata mentre i byte venivano caricati E lo spostamento del file memorizzato alla radice della pratica non è riuscito: il documento viene allora mantenuto nella cartella eliminata, dove il suo contenuto è ancora raggiungibile. False per tutto il resto, inclusa una normale archiviazione alla radice.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/documents?q=contract&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "name": "Contract_v2.docx",
      "size": 0,
      "version": 0,
      "folder": {
        "id": 1234,
        "name": "string",
        "path": "string"
      },
      "folder_deleted": true,
      "created_by_user_id": 1234,
      "created_by": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Elenca le cartelle della pratica

GET /api/agent/matters/{id}/folders

Elenca ogni cartella di una pratica, incluse quelle vuote: id, name, parent_id e il percorso separato da "/", ordinate per percorso. Passi un id di cartella come folder_id a documents.upload.init. Risponde 404 quando la pratica non è visibile all'utente.

Ambito
documents:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

q
stringal massimo 100 caratteri

Solo le cartelle il cui percorso contiene questo testo (maiuscole/minuscole e accenti ignorati), ad es. un nome di cartella.

Esempio: "Beadványok"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id della cartella: lo passi come folder_id a documents.upload.init.

name
string

Nome della cartella come mostrato in Flowyer.

parent_id
integer | null

Id della cartella padre; null per una cartella alla radice della pratica.

path
string

Percorso della cartella all'interno della pratica, separato da "/", ad es. "/Iratok/Beadványok" (lo stesso percorso che documents.list mostra per la cartella di un file).

updated_at
string <date-time> | null

Passi questo a documents.folders.rename come expected_updated_at.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/folders?q=Beadv%C3%A1nyok&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "name": "string",
      "parent_id": 1234,
      "path": "string",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Crea una cartella della pratica

POST /api/agent/matters/{id}/folders

Crea una cartella in una pratica, alla radice o sotto parent_id (una cartella della STESSA pratica). Il nome è testo semplice ("<" e ">" non sono consentiti). Archivi un documento al suo interno passando l'id restituito come folder_id a documents.upload.init. Risponde 404 quando la pratica non è visibile.

Ambito
documents:create
Permesso Flowyer
cases:create

Parametri di percorso

idobbligatorio
integer>= 1

Pratica a cui appartiene la cartella (deve essere visibile).

Esempio: 1234

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

nameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Nome della cartella, al massimo 255 caratteri. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Beadványok"
parent_id
integer | null>= 1

Id della cartella padre (da documents.folders) all'interno della STESSA pratica; ometta per una cartella alla radice della pratica.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id della cartella: lo passi come folder_id a documents.upload.init, oppure come parent_id a documents.folders.create.

name
string

Nome della cartella come mostrato in Flowyer.

parent_id
integer | null

Id della cartella padre; null per una cartella alla radice della pratica.

path
string

Percorso della cartella all'interno della pratica, separato da "/", ad es. "/Iratok/Beadványok".

updated_at
string <date-time> | null

Passi questo a documents.folders.rename come expected_updated_at.

created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id della cartella: lo passi come folder_id a documents.upload.init, oppure come parent_id a documents.folders.create.

name
string

Nome della cartella come mostrato in Flowyer.

parent_id
integer | null

Id della cartella padre; null per una cartella alla radice della pratica.

path
string

Percorso della cartella all'interno della pratica, separato da "/", ad es. "/Iratok/Beadványok".

updated_at
string <date-time> | null

Passi questo a documents.folders.rename come expected_updated_at.

created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/folders' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "name": "Beadványok"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "name": "string",
    "parent_id": 1234,
    "path": "string",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Avvia il caricamento del documento

POST /api/agent/matters/{id}/documents/uploads

Avvia un caricamento di documento: restituisce un upload_url firmato e un upload_token. Invii i byte lì con PUT, quindi richiami documents.upload.complete. La PUT è una semplice richiesta HTTPS esterna a questa API ed esterna agli strumenti MCP: un assistente privo di un proprio client HTTP dovrebbe chiedere all'utente di caricare il file in Flowyer.

Ambito
documents:create
Permesso Flowyer
cases:create

Parametri di percorso

idobbligatorio
integer>= 1

Pratica a cui appartiene il documento (deve essere visibile).

Corpo della richiesta application/json

filenameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Nome del file con estensione, ad es. "Contract.pdf". Testo semplice; "<" e ">" non sono consentiti. I tipi di file eseguibili e web vengono rifiutati (422 blocked_file_type).

Modello: ^[^<>]*$
Esempio: "Contract.pdf"
content_typeobbligatorio
stringalmeno 1 caratterial massimo 100 caratteri

Tipo MIME inviato sulla PUT, ad es. "application/pdf". Fa parte della firma e deve corrispondere esattamente.

Esempio: "application/pdf"
sizeobbligatorio
integer>= 1

Dimensione del file in byte, al massimo 104857600 (il limite di caricamento); una dimensione maggiore risponde 413 file_too_large.

Esempio: 248000
folder_id
integer | null>= 1

Cartella all'interno della pratica: un id di cartella da documents.folders (elenca anche le cartelle vuote). Ometta per la radice della pratica.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
upload_url
string

URL firmato. Invii qui i byte del file con PUT usando il content type indicato E l'header if_generation_match riportato di seguito: una semplice richiesta HTTPS effettuata dal suo client HTTP (nessuno strumento API o MCP la invia).

upload_token
string

Passi questo a documents.upload.complete dopo che la PUT è riuscita.

content_type
string

Invii esattamente questo Content-Type sulla PUT.

if_generation_match
string

Invii questo valore come header "x-goog-if-generation-match" sulla PUT (sempre "0"). Rende il caricamento monouso: la PUT viene accettata solo finché l'oggetto non esiste ancora, così l'URL firmato non può sovrascrivere un documento già archiviato.

object_key
string

Nome di archiviazione interno (per riferimento).

expires_in
integer

Secondi prima che l'URL di caricamento e il token scadano.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

413

Il corpo della richiesta è troppo grande (request_too_large), oppure il file supera il limite di caricamento (file_too_large; details.max indica il limite in byte).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/documents/uploads' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "filename": "Contract.pdf",
  "content_type": "application/pdf",
  "size": 248000
}'

Esempi di risposta

{
  "data": {
    "upload_url": "string",
    "upload_token": "string",
    "content_type": "string",
    "if_generation_match": "string",
    "object_key": "string",
    "expires_in": 0
  }
}

Completa il caricamento del documento

POST /api/agent/matters/{id}/documents

Completa un caricamento di documento: dopo che i byte sono stati inviati con PUT all'upload_url, registra il file sulla pratica come nuova versione. Passi l'upload_token da documents.upload.init. I metadati del file sono presi dal token, non da questa richiesta. Una cartella eliminata nel frattempo archivia il documento alla radice.

Ambito
documents:create
Permesso Flowyer
cases:create

Parametri di percorso

idobbligatorio
integer>= 1

Pratica a cui appartiene il documento (la stessa di init).

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

upload_tokenobbligatorio
stringalmeno 1 caratterial massimo 4096 caratteri

Il token restituito da documents.upload.init.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
name
string

Nome del file come mostrato in Flowyer: il nome memorizzato con il documento, oppure il suo nome di archiviazione quando è stato importato da un sistema più vecchio senza nome. documents.list è ordinato per nome memorizzato: i documenti che ne hanno uno vengono prima, in ordine alfabetico, poi quelli importati senza nome memorizzato, dal più vecchio (l'ordine in cui sono stati archiviati in Flowyer), che pertanto non sono ordinati per il nome qui mostrato. L'ordine è lo stesso in ogni pagina, quindi limit e offset scorrono l'elenco senza ripetizioni né lacune.

Esempio: "Contract_v2.docx"
size
integer | null

Byte.

version
integer

Numero di versione corrente del file.

folder
object | null

La cartella in cui è archiviato il documento, oppure null alla radice della pratica. documents.upload.complete risponde null quando la cartella scelta in documents.upload.init è stata eliminata mentre i byte venivano caricati: il documento viene allora archiviato alla radice della pratica, dove Flowyer lo mostra. Se la radice contiene già un documento con quel nome, il caricamento viene archiviato con un nome con suffisso ("Contract_2.pdf") invece di diventare una nuova versione di quel documento non correlato; il 201 restituisce il name memorizzato.

Campi di folder
id
integer
name
string
path
string

Percorso della cartella all'interno della pratica, separato da "/".

folder_deleted
boolean

True quando il documento è archiviato in una cartella che non esiste più, che l'elenco file di Flowyer non mostra (folder è null per esso, come per un documento alla radice della pratica). documents.upload.complete risponde true solo se la cartella è stata eliminata mentre i byte venivano caricati E lo spostamento del file memorizzato alla radice della pratica non è riuscito: il documento viene allora mantenuto nella cartella eliminata, dove il suo contenuto è ancora raggiungibile. False per tutto il resto, inclusa una normale archiviazione alla radice.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato. È anche la risposta quando questo upload_token è già stato completato.

dataobbligatorio
object
Campi di data
id
integer
name
string

Nome del file come mostrato in Flowyer: il nome memorizzato con il documento, oppure il suo nome di archiviazione quando è stato importato da un sistema più vecchio senza nome. documents.list è ordinato per nome memorizzato: i documenti che ne hanno uno vengono prima, in ordine alfabetico, poi quelli importati senza nome memorizzato, dal più vecchio (l'ordine in cui sono stati archiviati in Flowyer), che pertanto non sono ordinati per il nome qui mostrato. L'ordine è lo stesso in ogni pagina, quindi limit e offset scorrono l'elenco senza ripetizioni né lacune.

Esempio: "Contract_v2.docx"
size
integer | null

Byte.

version
integer

Numero di versione corrente del file.

folder
object | null

La cartella in cui è archiviato il documento, oppure null alla radice della pratica. documents.upload.complete risponde null quando la cartella scelta in documents.upload.init è stata eliminata mentre i byte venivano caricati: il documento viene allora archiviato alla radice della pratica, dove Flowyer lo mostra. Se la radice contiene già un documento con quel nome, il caricamento viene archiviato con un nome con suffisso ("Contract_2.pdf") invece di diventare una nuova versione di quel documento non correlato; il 201 restituisce il name memorizzato.

Campi di folder
id
integer
name
string
path
string

Percorso della cartella all'interno della pratica, separato da "/".

folder_deleted
boolean

True quando il documento è archiviato in una cartella che non esiste più, che l'elenco file di Flowyer non mostra (folder è null per esso, come per un documento alla radice della pratica). documents.upload.complete risponde true solo se la cartella è stata eliminata mentre i byte venivano caricati E lo spostamento del file memorizzato alla radice della pratica non è riuscito: il documento viene allora mantenuto nella cartella eliminata, dove il suo contenuto è ancora raggiungibile. False per tutto il resto, inclusa una normale archiviazione alla radice.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. upload_not_finished: il file non ha ancora raggiunto l'archiviazione; completi la PUT verso upload_url, quindi richiami complete. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large), oppure il file supera il limite di caricamento (file_too_large; details.max indica il limite in byte).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/documents' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "upload_token": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "name": "Contract_v2.docx",
    "size": 0,
    "version": 0,
    "folder": {
      "id": 1234,
      "name": "string",
      "path": "string"
    },
    "folder_deleted": true,
    "created_by_user_id": 1234,
    "created_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Scarica il documento

GET /api/agent/documents/{id}/download

Restituisce un URL firmato di breve durata per scaricare un documento tramite id, se la relativa pratica è visibile. Esegua una GET sull'url per recuperare i byte; scade in pochi minuti.

Ambito
documents:download
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del documento (da documents.list).

Risposte

200

OK.

dataobbligatorio
object
Campi di data
download_url
string

URL firmato. Esegua una GET per scaricare i byte del file.

filename
string

Nome del file per il download.

size
integer | null

Byte.

expires_in
integer

Secondi mancanti alla scadenza dell'URL.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/documents/1234/download' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "download_url": "string",
    "filename": "string",
    "size": 0,
    "expires_in": 0
  }
}

Rinomina il documento

PATCH /api/agent/documents/{id}

Rinomina un documento (solo il nome visualizzato; il contenuto del file resta invariato). Il nuovo nome deve essere univoco nella stessa cartella della pratica. Passi expected_updated_at ottenuto dall'ultima lettura; una modifica in conflitto risponde con 409.

Ambito
documents:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

nameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Nuovo nome del file, al massimo 255 caratteri COMPRESA l'estensione. L'estensione corrente viene mantenuta se non ne indica una, e conta ai fini dei 255 (quindi un nome senza estensione per "Beadvany.pdf" può avere al massimo 251 caratteri). Testo semplice; "<" e ">" non sono consentiti, quindi un documento il cui nome memorizzato ne contiene uno può essere rinominato solo in Flowyer.

Modello: ^[^<>]*$
Esempio: "Contract_signed.pdf"

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
name
string

Nome del file come mostrato in Flowyer: il nome memorizzato con il documento, oppure il suo nome di archiviazione quando è stato importato da un sistema più vecchio senza nome. documents.list è ordinato per nome memorizzato: i documenti che ne hanno uno vengono prima, in ordine alfabetico, poi quelli importati senza nome memorizzato, dal più vecchio (l'ordine in cui sono stati archiviati in Flowyer), che pertanto non sono ordinati per il nome qui mostrato. L'ordine è lo stesso in ogni pagina, quindi limit e offset scorrono l'elenco senza ripetizioni né lacune.

Esempio: "Contract_v2.docx"
size
integer | null

Byte.

version
integer

Numero di versione corrente del file.

folder
object | null

La cartella in cui è archiviato il documento, oppure null alla radice della pratica. documents.upload.complete risponde null quando la cartella scelta in documents.upload.init è stata eliminata mentre i byte venivano caricati: il documento viene allora archiviato alla radice della pratica, dove Flowyer lo mostra. Se la radice contiene già un documento con quel nome, il caricamento viene archiviato con un nome con suffisso ("Contract_2.pdf") invece di diventare una nuova versione di quel documento non correlato; il 201 restituisce il name memorizzato.

Campi di folder
id
integer
name
string
path
string

Percorso della cartella all'interno della pratica, separato da "/".

folder_deleted
boolean

True quando il documento è archiviato in una cartella che non esiste più, che l'elenco file di Flowyer non mostra (folder è null per esso, come per un documento alla radice della pratica). documents.upload.complete risponde true solo se la cartella è stata eliminata mentre i byte venivano caricati E lo spostamento del file memorizzato alla radice della pratica non è riuscito: il documento viene allora mantenuto nella cartella eliminata, dove il suo contenuto è ancora raggiungibile. False per tutto il resto, inclusa una normale archiviazione alla radice.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at), oppure un altro documento nella stessa cartella ha già questo nome (duplicate_name; scelga un altro nome, non riprovi con lo stesso).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/documents/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "name": "Contract_signed.pdf"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "name": "Contract_v2.docx",
    "size": 0,
    "version": 0,
    "folder": {
      "id": 1234,
      "name": "string",
      "path": "string"
    },
    "folder_deleted": true,
    "created_by_user_id": 1234,
    "created_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Rinomina la cartella della pratica

PATCH /api/agent/folders/{id}

Rinomina una cartella (solo il suo nome; i suoi file e sottocartelle mantengono la loro posizione). Il nome è testo semplice ("<" e ">" non sono consentiti). Passi expected_updated_at dalla sua ultima lettura (documents.folders lo elenca); una modifica in conflitto risponde 409.

Ambito
documents:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

nameobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Nuovo nome della cartella, al massimo 255 caratteri. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Beadványok"

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id della cartella: lo passi come folder_id a documents.upload.init, oppure come parent_id a documents.folders.create.

name
string

Nome della cartella come mostrato in Flowyer.

parent_id
integer | null

Id della cartella padre; null per una cartella alla radice della pratica.

path
string

Percorso della cartella all'interno della pratica, separato da "/", ad es. "/Iratok/Beadványok".

updated_at
string <date-time> | null

Passi questo a documents.folders.rename come expected_updated_at.

updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/folders/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "name": "Beadványok"
}'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "name": "string",
    "parent_id": 1234,
    "path": "string",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Base di conoscenza

Elenca gli articoli della knowledge base

GET /api/agent/knowledge/articles

Elenca gli articoli della knowledge base che l'utente può vedere (quelli propri dell'autore, gli articoli globali e gli articoli condivisi con il ruolo dell'utente). Tutti gli stati per impostazione predefinita; filtri per stato, oppure passi q per effettuare una ricerca full-text su titoli, estratti, contenuto e tag.

Ambito
knowledge:read

Parametri di query

q
string | nullal massimo 255 caratteri

Termine di ricerca full-text (titoli, estratti, contenuto e nomi dei tag). Gli operatori booleani vengono rimossi.

Esempio: "felmondási idő"
status
string | null

Solo gli articoli con questo stato. Lo ometta per elencare ogni stato.

Valori ammessi: "draft" "published" "archived"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 9876
slug
string

Slug dell'URL generato dal server.

Esempio: "felmondasi-ido"
title
string
Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML formattato, come memorizzato).

content
string

Il corpo dell'articolo come memorizzato (HTML formattato).

status
string
Valori ammessi: "draft" "published" "archived"
is_featured
boolean

Se l'articolo è fissato sulla home page della KB (non impostabile tramite l'API).

category_id
integer | null
category_name
string | null
author_id
integer

Id utente dell'autore; 0 per un articolo globale (predefinito).

author_name
string | null
editor_id
integer | null

Id utente dell'ultimo editor, oppure null se mai modificato.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id dei ruoli con cui l'articolo è condiviso (vuoto = solo l'autore/globale).

tags
string[]

Nomi dei tag sull'articolo.

published_at
string <date-time> | null

Quando l'articolo è stato pubblicato per la prima volta, oppure null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/knowledge/articles?q=felmond%C3%A1si%20id%C5%91&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 9876,
      "slug": "felmondasi-ido",
      "title": "Felmondási idő a munka törvénykönyvében",
      "excerpt": "string",
      "content": "string",
      "status": "draft",
      "is_featured": true,
      "category_id": 1234,
      "category_name": "string",
      "author_id": 1234,
      "author_name": "string",
      "editor_id": 1234,
      "editor_name": "string",
      "views_count": 0,
      "downloads_count": 0,
      "shared_roles": [
        0
      ],
      "tags": [
        "string"
      ],
      "published_at": "2026-10-30T09:15:00+01:00",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni l'articolo della knowledge base

GET /api/agent/knowledge/articles/{id}

Restituisce un articolo della knowledge base, incluso il suo contenuto completo, i tag e i ruoli con cui è condiviso. Risponde con 404 quando l'articolo non esiste o l'utente non può vederlo.

Ambito
knowledge:read

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'articolo.

Esempio: 9876

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
slug
string

Slug dell'URL generato dal server.

Esempio: "felmondasi-ido"
title
string
Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML formattato, come memorizzato).

content
string

Il corpo dell'articolo come memorizzato (HTML formattato).

status
string
Valori ammessi: "draft" "published" "archived"
is_featured
boolean

Se l'articolo è fissato sulla home page della KB (non impostabile tramite l'API).

category_id
integer | null
category_name
string | null
author_id
integer

Id utente dell'autore; 0 per un articolo globale (predefinito).

author_name
string | null
editor_id
integer | null

Id utente dell'ultimo editor, oppure null se mai modificato.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id dei ruoli con cui l'articolo è condiviso (vuoto = solo l'autore/globale).

tags
string[]

Nomi dei tag sull'articolo.

published_at
string <date-time> | null

Quando l'articolo è stato pubblicato per la prima volta, oppure null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/knowledge/articles/9876' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "slug": "felmondasi-ido",
    "title": "Felmondási idő a munka törvénykönyvében",
    "excerpt": "string",
    "content": "string",
    "status": "draft",
    "is_featured": true,
    "category_id": 1234,
    "category_name": "string",
    "author_id": 1234,
    "author_name": "string",
    "editor_id": 1234,
    "editor_name": "string",
    "views_count": 0,
    "downloads_count": 0,
    "shared_roles": [
      0
    ],
    "tags": [
      "string"
    ],
    "published_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  }
}

Crea un articolo della knowledge base

POST /api/agent/knowledge/articles

Crea un articolo della knowledge base con l'utente della chiave come autore. Lo slug viene generato dal titolo. La categoria deve esistere ed essere attiva. Lo condivida con i ruoli tramite shared_roles (altrimenti lo vede solo l'autore). content ed excerpt sono HTML e vengono sanificati lato server.

Ambito
knowledge:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

titleobbligatorio
stringal massimo 500 caratteri

Titolo dell'articolo. Testo semplice.

Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML consentito, sanificato lato server), al massimo 200 caratteri.

contentobbligatorio
string

Il corpo dell'articolo. HTML formattato, sanificato lato server con il profilo della knowledge base.

category_idobbligatorio
integer>= 1

Id di una categoria della knowledge base esistente e attiva.

Esempio: 12
statusobbligatorio
string

draft, published o archived. published imposta published_at.

Valori ammessi: "draft" "published" "archived"
tags
string[] | null

Nomi dei tag; i nuovi tag vengono creati secondo necessità.

shared_roles
integer[] | null

Id dei ruoli con cui condividere l'articolo. Vuoto significa che solo l'autore può vederlo.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
slug
string

Slug dell'URL generato dal server.

Esempio: "felmondasi-ido"
title
string
Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML formattato, come memorizzato).

content
string

Il corpo dell'articolo come memorizzato (HTML formattato).

status
string
Valori ammessi: "draft" "published" "archived"
is_featured
boolean

Se l'articolo è fissato sulla home page della KB (non impostabile tramite l'API).

category_id
integer | null
category_name
string | null
author_id
integer

Id utente dell'autore; 0 per un articolo globale (predefinito).

author_name
string | null
editor_id
integer | null

Id utente dell'ultimo editor, oppure null se mai modificato.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id dei ruoli con cui l'articolo è condiviso (vuoto = solo l'autore/globale).

tags
string[]

Nomi dei tag sull'articolo.

published_at
string <date-time> | null

Quando l'articolo è stato pubblicato per la prima volta, oppure null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
slug
string

Slug dell'URL generato dal server.

Esempio: "felmondasi-ido"
title
string
Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML formattato, come memorizzato).

content
string

Il corpo dell'articolo come memorizzato (HTML formattato).

status
string
Valori ammessi: "draft" "published" "archived"
is_featured
boolean

Se l'articolo è fissato sulla home page della KB (non impostabile tramite l'API).

category_id
integer | null
category_name
string | null
author_id
integer

Id utente dell'autore; 0 per un articolo globale (predefinito).

author_name
string | null
editor_id
integer | null

Id utente dell'ultimo editor, oppure null se mai modificato.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id dei ruoli con cui l'articolo è condiviso (vuoto = solo l'autore/globale).

tags
string[]

Nomi dei tag sull'articolo.

published_at
string <date-time> | null

Quando l'articolo è stato pubblicato per la prima volta, oppure null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/knowledge/articles' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "title": "Felmondási idő a munka törvénykönyvében",
  "content": "string",
  "category_id": 12,
  "status": "draft"
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "slug": "felmondasi-ido",
    "title": "Felmondási idő a munka törvénykönyvében",
    "excerpt": "string",
    "content": "string",
    "status": "draft",
    "is_featured": true,
    "category_id": 1234,
    "category_name": "string",
    "author_id": 1234,
    "author_name": "string",
    "editor_id": 1234,
    "editor_name": "string",
    "views_count": 0,
    "downloads_count": 0,
    "shared_roles": [
      0
    ],
    "tags": [
      "string"
    ],
    "published_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Aggiorna l'articolo della knowledge base

PATCH /api/agent/knowledge/articles/{id}

Modifica un articolo della knowledge base: titolo (lo slug viene ricalcolato), estratto, contenuto, categoria, stato, tag o ruoli condivisi. Solo l'autore (o chiunque, per un articolo globale) può modificarlo. Passi expected_updated_at; una modifica in conflitto risponde con 409. content ed excerpt vengono sanificati lato server.

Ambito
knowledge:update

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

title
string | null

Titolo dell'articolo (testo semplice). null mantiene il titolo corrente; un nuovo titolo ricalcola lo slug.

excerpt
string | null

Breve riepilogo (HTML consentito, sanificato), al massimo 200 caratteri come NUOVO valore. Vuoto/null lo cancella; lo ometta per mantenerlo.

content
string | null

Il corpo dell'articolo (HTML formattato, sanificato). null mantiene il contenuto corrente; non può essere cancellato.

category_id
integer | null>= 1

Sposta l'articolo in questa categoria esistente e attiva. null mantiene quella corrente.

status
string | null

draft, published o archived. Il primo passaggio a published imposta published_at; non viene mai cancellato. null mantiene lo stato corrente.

Valori ammessi: "draft" "published" "archived"
tags
string[] | null

Sostituisce l'intero insieme di tag (i nuovi tag vengono creati). Un array vuoto cancella tutti i tag; lo ometta per mantenerli.

shared_roles
integer[] | null

Sostituisce l'intero insieme di ruoli condivisi. Un array vuoto rimuove tutte le condivisioni (lo vede solo l'autore); lo ometta per mantenerlo.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
slug
string

Slug dell'URL generato dal server.

Esempio: "felmondasi-ido"
title
string
Esempio: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Breve riepilogo (HTML formattato, come memorizzato).

content
string

Il corpo dell'articolo come memorizzato (HTML formattato).

status
string
Valori ammessi: "draft" "published" "archived"
is_featured
boolean

Se l'articolo è fissato sulla home page della KB (non impostabile tramite l'API).

category_id
integer | null
category_name
string | null
author_id
integer

Id utente dell'autore; 0 per un articolo globale (predefinito).

author_name
string | null
editor_id
integer | null

Id utente dell'ultimo editor, oppure null se mai modificato.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id dei ruoli con cui l'articolo è condiviso (vuoto = solo l'autore/globale).

tags
string[]

Nomi dei tag sull'articolo.

published_at
string <date-time> | null

Quando l'articolo è stato pubblicato per la prima volta, oppure null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/knowledge/articles/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "title": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "slug": "felmondasi-ido",
    "title": "Felmondási idő a munka törvénykönyvében",
    "excerpt": "string",
    "content": "string",
    "status": "draft",
    "is_featured": true,
    "category_id": 1234,
    "category_name": "string",
    "author_id": 1234,
    "author_name": "string",
    "editor_id": 1234,
    "editor_name": "string",
    "views_count": 0,
    "downloads_count": 0,
    "shared_roles": [
      0
    ],
    "tags": [
      "string"
    ],
    "published_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Elenca le categorie della knowledge base

GET /api/agent/knowledge/categories

Elenca le categorie della knowledge base che l'utente può vedere: categorie predefinite integrate, quelle proprie dell'utente e quelle condivise con il ruolo dell'utente. Ordinate come in Flowyer (posizione di ordinamento, poi nome).

Ambito
knowledge:read

Parametri di query

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 42
slug
string

Slug dell'URL, generato dal nome.

Esempio: "munkajog"
name
string
Esempio: "Munkajog"
description
string | null

Descrizione in testo semplice, oppure null.

icon
string | null

Identificatore dell'icona mostrata accanto alla categoria, oppure null.

order_column
integer

Posizione di ordinamento tra le categorie dello stesso livello.

Esempio: 0
is_active
boolean
parent_id
integer | null

Id della categoria padre, oppure null per una categoria radice.

author_id
integer

Id utente del creatore; 0 per una categoria predefinita integrata visibile a tutti.

author_name
string | null

Nome visualizzato del creatore, oppure null per una categoria predefinita.

articles_count
integer

Numero di articoli pubblicati in questa categoria che il chiamante può vedere.

shared_roles
integer[]

Id dei ruoli con cui questa categoria è condivisa. Vuoto significa che la vede solo l'autore (una categoria predefinita con author_id 0 è visibile a tutti).

created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/knowledge/categories?limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 42,
      "slug": "munkajog",
      "name": "Munkajog",
      "description": "string",
      "icon": "string",
      "order_column": 0,
      "is_active": true,
      "parent_id": 1234,
      "author_id": 1234,
      "author_name": "string",
      "articles_count": 0,
      "shared_roles": [
        1
      ],
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni la categoria della knowledge base

GET /api/agent/knowledge/categories/{id}

Restituisce una categoria della knowledge base. Risponde con 404 quando la categoria non esiste o non è visibile all'utente proprietario di questa chiave API.

Ambito
knowledge:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della categoria.

Esempio: 42

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 42
slug
string

Slug dell'URL, generato dal nome.

Esempio: "munkajog"
name
string
Esempio: "Munkajog"
description
string | null

Descrizione in testo semplice, oppure null.

icon
string | null

Identificatore dell'icona mostrata accanto alla categoria, oppure null.

order_column
integer

Posizione di ordinamento tra le categorie dello stesso livello.

Esempio: 0
is_active
boolean
parent_id
integer | null

Id della categoria padre, oppure null per una categoria radice.

author_id
integer

Id utente del creatore; 0 per una categoria predefinita integrata visibile a tutti.

author_name
string | null

Nome visualizzato del creatore, oppure null per una categoria predefinita.

articles_count
integer

Numero di articoli pubblicati in questa categoria che il chiamante può vedere.

shared_roles
integer[]

Id dei ruoli con cui questa categoria è condivisa. Vuoto significa che la vede solo l'autore (una categoria predefinita con author_id 0 è visibile a tutti).

created_at
string <date-time> | null
updated_at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/knowledge/categories/42' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 42,
    "slug": "munkajog",
    "name": "Munkajog",
    "description": "string",
    "icon": "string",
    "order_column": 0,
    "is_active": true,
    "parent_id": 1234,
    "author_id": 1234,
    "author_name": "string",
    "articles_count": 0,
    "shared_roles": [
      1
    ],
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  }
}

Crea una categoria della knowledge base

POST /api/agent/knowledge/categories

Crea una categoria della knowledge base. Lo slug dell'URL viene generato dal nome. La condivida con i ruoli tramite shared_roles, oppure li ometta in modo che solo Lei (l'autore) possa vederla. Un parent_id, se fornito, deve essere una categoria esistente e attiva.

Ambito
knowledge:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

nameobbligatorio
stringal massimo 255 caratteri

Nome della categoria. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Munkajog"
description
string | null

Descrizione facoltativa, testo semplice.

parent_id
integer | null>= 1

Id della categoria padre (deve esistere ed essere attiva). Lo ometta per una categoria radice.

icon
string | nullal massimo 100 caratteri

Identificatore dell'icona facoltativo. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
is_active
boolean | null

Se la categoria è attiva. Predefinito true.

Predefinito: true
order_column
integer | null>= 0

Posizione di ordinamento tra le categorie dello stesso livello. Predefinito 0.

Esempio: 0
shared_roles
integer[] | null

Id dei ruoli con cui condividere questa categoria. Li ometta in modo che solo Lei (l'autore) possa vederla.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 42
slug
string

Slug dell'URL, generato dal nome.

Esempio: "munkajog"
name
string
Esempio: "Munkajog"
description
string | null

Descrizione in testo semplice, oppure null.

icon
string | null

Identificatore dell'icona mostrata accanto alla categoria, oppure null.

order_column
integer

Posizione di ordinamento tra le categorie dello stesso livello.

Esempio: 0
is_active
boolean
parent_id
integer | null

Id della categoria padre, oppure null per una categoria radice.

author_id
integer

Id utente del creatore; 0 per una categoria predefinita integrata visibile a tutti.

author_name
string | null

Nome visualizzato del creatore, oppure null per una categoria predefinita.

articles_count
integer

Numero di articoli pubblicati in questa categoria che il chiamante può vedere.

shared_roles
integer[]

Id dei ruoli con cui questa categoria è condivisa. Vuoto significa che la vede solo l'autore (una categoria predefinita con author_id 0 è visibile a tutti).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 42
slug
string

Slug dell'URL, generato dal nome.

Esempio: "munkajog"
name
string
Esempio: "Munkajog"
description
string | null

Descrizione in testo semplice, oppure null.

icon
string | null

Identificatore dell'icona mostrata accanto alla categoria, oppure null.

order_column
integer

Posizione di ordinamento tra le categorie dello stesso livello.

Esempio: 0
is_active
boolean
parent_id
integer | null

Id della categoria padre, oppure null per una categoria radice.

author_id
integer

Id utente del creatore; 0 per una categoria predefinita integrata visibile a tutti.

author_name
string | null

Nome visualizzato del creatore, oppure null per una categoria predefinita.

articles_count
integer

Numero di articoli pubblicati in questa categoria che il chiamante può vedere.

shared_roles
integer[]

Id dei ruoli con cui questa categoria è condivisa. Vuoto significa che la vede solo l'autore (una categoria predefinita con author_id 0 è visibile a tutti).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/knowledge/categories' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "name": "Munkajog",
  "order_column": 0
}'

Esempi di risposta

{
  "data": {
    "id": 42,
    "slug": "munkajog",
    "name": "Munkajog",
    "description": "string",
    "icon": "string",
    "order_column": 0,
    "is_active": true,
    "parent_id": 1234,
    "author_id": 1234,
    "author_name": "string",
    "articles_count": 0,
    "shared_roles": [
      1
    ],
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Aggiorna la categoria della knowledge base

PATCH /api/agent/knowledge/categories/{id}

Modifica una categoria della knowledge base: nome (lo slug lo segue), descrizione, icona, categoria padre, flag di attività, posizione di ordinamento o i ruoli con cui è condivisa. Solo l'autore può modificarla (una categoria predefinita integrata è modificabile da chiunque). Passi expected_updated_at; una modifica in conflitto risponde con 409.

Ambito
knowledge:update

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

name
string | nullalmeno 1 caratteri

Nome della categoria. Al massimo 255 caratteri come NUOVO valore; non è possibile introdurre "<" e ">", ma un nome memorizzato più lungo o che li contiene può essere restituito invariato. null mantiene il nome corrente.

description
string | null

Descrizione in testo semplice. null la cancella.

parent_id
integer | null>= 1

Sposta la categoria sotto questa categoria padre (deve esistere, essere attiva e non creare un ciclo), oppure null per renderla una categoria radice.

icon
string | null

Identificatore dell'icona. Al massimo 100 caratteri come NUOVO valore; non è possibile introdurre "<" e ">". null lo cancella.

is_active
boolean | null

Flag di attività. Lo ometta o usi null per mantenere il valore corrente.

order_column
integer | null>= 0

Posizione di ordinamento tra le categorie dello stesso livello. Lo ometta o usi null per mantenere il valore corrente.

shared_roles
integer[] | null

Sostituisce l'insieme di id dei ruoli con cui questa categoria è condivisa. Un array vuoto rimuove tutte le condivisioni (la vede solo l'autore). Lo ometta per lasciare invariata la condivisione.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 42
slug
string

Slug dell'URL, generato dal nome.

Esempio: "munkajog"
name
string
Esempio: "Munkajog"
description
string | null

Descrizione in testo semplice, oppure null.

icon
string | null

Identificatore dell'icona mostrata accanto alla categoria, oppure null.

order_column
integer

Posizione di ordinamento tra le categorie dello stesso livello.

Esempio: 0
is_active
boolean
parent_id
integer | null

Id della categoria padre, oppure null per una categoria radice.

author_id
integer

Id utente del creatore; 0 per una categoria predefinita integrata visibile a tutti.

author_name
string | null

Nome visualizzato del creatore, oppure null per una categoria predefinita.

articles_count
integer

Numero di articoli pubblicati in questa categoria che il chiamante può vedere.

shared_roles
integer[]

Id dei ruoli con cui questa categoria è condivisa. Vuoto significa che la vede solo l'autore (una categoria predefinita con author_id 0 è visibile a tutti).

created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/knowledge/categories/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "name": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 42,
    "slug": "munkajog",
    "name": "Munkajog",
    "description": "string",
    "icon": "string",
    "order_column": 0,
    "is_active": true,
    "parent_id": 1234,
    "author_id": 1234,
    "author_name": "string",
    "articles_count": 0,
    "shared_roles": [
      1
    ],
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Email

Elenca le email della pratica

GET /api/agent/matters/{id}/emails

Elenca le email salvate su una pratica: nome e indirizzo del mittente, oggetto, dimensione e il collega che ha salvato ciascuna, prima le più recenti per data di invio. Solo intestazione e metadati, mai il corpo o l'HTML grezzo. Usi emails.get per il corpo in testo semplice di un singolo messaggio.

Ambito
emails:read
Permesso Flowyer
emails:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

q
stringal massimo 100 caratteri

Filtra per oggetto, nome del mittente o indirizzo del mittente (ignorando accenti e maiuscole/minuscole). Non il corpo.

Esempio: "invoice"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id dell'email (da usare con emails.get).

Esempio: 1234
from_name
string | null

Nome visualizzato della parte esterna. L'archivio non conserva colonne di direzione o destinatario, quindi questa è sempre la parte esterna, mai un collega, e l'API non può dire se l'email fosse in entrata o in uscita.

from_address
string | null

Indirizzo SMTP della parte esterna.

subject
string | null
sent_at
string <date-time> | null

Quando il messaggio è stato inviato. Il fuso orario del valore memorizzato è incoerente a seconda del percorso di acquisizione (il worker IMAP memorizza UTC, il componente aggiuntivo di Outlook memorizza un'ora locale del fuso dello studio), quindi è al meglio possibile e l'ordinamento dell'elenco in base ad esso può discostarsi dell'offset UTC dello studio tra le varie sorgenti. created_at è il timestamp affidabile.

size
integer | null

Byte del file .eml/.msg memorizzato.

extension
string | null

"msg" (componente aggiuntivo di Outlook) o "eml" (IMAP / predefinito); null su alcune righe legacy.

saved_by_user_id
integer | null

Id utente del collega che ha salvato l'email in Flowyer.

saved_by
string | null

Nome visualizzato di quel collega.

created_at
string <date-time> | null

Quando l'email è stata salvata in Flowyer (ora locale del fuso dello studio). Il timestamp affidabile per una paginazione stabile.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/emails?q=invoice&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "from_name": "string",
      "from_address": "string",
      "subject": "string",
      "sent_at": "2026-10-30T09:15:00+01:00",
      "size": 0,
      "extension": "string",
      "saved_by_user_id": 1234,
      "saved_by": "string",
      "created_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni l'email

GET /api/agent/emails/{id}

Restituisce un'email salvata di una pratica con il suo corpo in testo semplice (mittente, oggetto, dimensione e chi l'ha salvata). Il corpo HTML grezzo non viene mai restituito. Risponde 404 quando l'email non esiste o la sua pratica non è visibile all'utente proprietario di questa chiave API.

Ambito
emails:read
Permesso Flowyer
emails:read

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'email.

Esempio: 1234

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 1234
matter
object | null

La pratica sotto cui è archiviata l'email, oppure null per un'email senza pratica (salvata al di fuori di qualsiasi causa).

Campi di matter
id
integer
case_number
string
from_name
string | null

Nome visualizzato della parte esterna (mai un collega; l'archivio non ha una colonna di direzione).

from_address
string | null

Indirizzo SMTP della parte esterna.

subject
string | null
body
string | null

Il corpo del messaggio in testo semplice. Il corpo HTML grezzo non viene deliberatamente mai restituito (HTML di terze parti non attendibile). Testo semplice ottenuto al meglio possibile: se l'HTML originale conteneva <style>/<script>, il loro testo interno potrebbe sopravvivere al suo interno.

sent_at
string <date-time> | null

Quando il messaggio è stato inviato. Il fuso orario è incoerente a seconda del percorso di acquisizione (IMAP memorizza UTC, il componente aggiuntivo di Outlook un'ora locale del fuso dello studio); created_at è il timestamp affidabile.

size
integer | null

Byte del file .eml/.msg memorizzato.

extension
string | null

"msg" o "eml"; null su alcune righe legacy.

saved_by_user_id
integer | null

Id utente del collega che ha salvato l'email in Flowyer.

saved_by
string | null

Nome visualizzato di quel collega.

created_at
string <date-time> | null

Quando l'email è stata salvata in Flowyer (ora locale del fuso dello studio).

updated_at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/emails/1234' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 1234,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "from_name": "string",
    "from_address": "string",
    "subject": "string",
    "body": "string",
    "sent_at": "2026-10-30T09:15:00+01:00",
    "size": 0,
    "extension": "string",
    "saved_by_user_id": 1234,
    "saved_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00"
  }
}

Cronologia processuale

Elenca la cronologia processuale della pratica

GET /api/agent/matters/{id}/litigation

Elenca le voci della cronologia processuale (pertörténet) di una pratica, prima l'evento più recente: una nota datata con un titolo, una descrizione HTML e un luogo. Risponde 404 quando la pratica non è visibile all'utente.

Ambito
litigation:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 4521
title
string

Titolo della voce. Testo semplice.

Esempio: "Első tárgyalás elhalasztva"
description
string | null

Dettagli della voce come HTML formattato, sanificato lato server.

location
string | null

Dove è avvenuto (testo semplice), ad es. un'aula di tribunale; può essere null.

event_date
string <date> | null

Giorno della voce, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

user_id
integer | null

Autore (l'utente che ha creato la voce).

created_by
string | null

Nome visualizzato dell'autore.

last_editor_id
integer | null

Utente che ha modificato per ultimo la voce.

last_editor
string | null

Nome visualizzato dell'ultimo editor.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a litigation.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/litigation?limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 4521,
      "title": "Első tárgyalás elhalasztva",
      "description": "string",
      "location": "string",
      "event_date": "2026-10-30",
      "user_id": 1234,
      "created_by": "string",
      "last_editor_id": 1234,
      "last_editor": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Crea una voce della cronologia processuale

POST /api/agent/matters/{id}/litigation

Aggiunge una voce della cronologia processuale (pertörténet) a una pratica: un titolo (testo semplice, "<"/">" non consentiti), una descrizione HTML facoltativa (sanificata lato server), un luogo facoltativo e una data dell'evento (predefinita a oggi). Risponde 404 quando la pratica non è visibile.

Ambito
litigation:create
Permesso Flowyer
cases:create

Parametri di percorso

idobbligatorio
integer>= 1

Pratica a cui appartiene la voce (deve essere visibile).

Esempio: 1234

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

titleobbligatorio
stringalmeno 1 caratterial massimo 2000 caratteri

Titolo della voce, al massimo 2000 caratteri. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Első tárgyalás elhalasztva"
description
string | null

Dettagli della voce. HTML formattato, sanificato lato server con il profilo della knowledge base.

location
string | nullal massimo 255 caratteri

Dove è avvenuto (testo semplice, al massimo 255 caratteri); "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Fővárosi Törvényszék, 215. tárgyaló"
event_date
string <date> | null

Giorno della voce, YYYY-MM-DD. Predefinito a oggi (fuso orario dello studio).

Esempio: "2026-11-15"
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4521
title
string

Titolo della voce. Testo semplice.

Esempio: "Első tárgyalás elhalasztva"
description
string | null

Dettagli della voce come HTML formattato, sanificato lato server.

location
string | null

Dove è avvenuto (testo semplice), ad es. un'aula di tribunale; può essere null.

event_date
string <date> | null

Giorno della voce, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

user_id
integer | null

Autore (l'utente che ha creato la voce).

created_by
string | null

Nome visualizzato dell'autore.

last_editor_id
integer | null

Utente che ha modificato per ultimo la voce.

last_editor
string | null

Nome visualizzato dell'ultimo editor.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a litigation.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4521
title
string

Titolo della voce. Testo semplice.

Esempio: "Első tárgyalás elhalasztva"
description
string | null

Dettagli della voce come HTML formattato, sanificato lato server.

location
string | null

Dove è avvenuto (testo semplice), ad es. un'aula di tribunale; può essere null.

event_date
string <date> | null

Giorno della voce, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

user_id
integer | null

Autore (l'utente che ha creato la voce).

created_by
string | null

Nome visualizzato dell'autore.

last_editor_id
integer | null

Utente che ha modificato per ultimo la voce.

last_editor
string | null

Nome visualizzato dell'ultimo editor.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a litigation.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/litigation' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "title": "Első tárgyalás elhalasztva",
  "location": "Fővárosi Törvényszék, 215. tárgyaló",
  "event_date": "2026-11-15"
}'

Esempi di risposta

{
  "data": {
    "id": 4521,
    "title": "Első tárgyalás elhalasztva",
    "description": "string",
    "location": "string",
    "event_date": "2026-10-30",
    "user_id": 1234,
    "created_by": "string",
    "last_editor_id": 1234,
    "last_editor": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna la voce della cronologia processuale

PATCH /api/agent/litigation/{id}

Modifica una voce della cronologia processuale (pertörténet): titolo, descrizione, luogo o data dell'evento. Vengono scritti solo i campi che invia; la descrizione viene sanificata lato server. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409.

Ambito
litigation:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

title
string | nullalmeno 1 caratterial massimo 2000 caratteri

Nuovo titolo, al massimo 2000 caratteri (testo semplice; "<"/">" non consentiti). Lo ometta per mantenere quello corrente.

Modello: ^[^<>]*$
Esempio: "Ítélethirdetés elhalasztva"
description
string | null

Nuovi dettagli (HTML formattato, sanificato). Li ometta per mantenere quelli correnti; null/vuoto li cancella.

location
string | nullal massimo 255 caratteri

Nuovo luogo (testo semplice, al massimo 255 caratteri; "<"/">" non consentiti). Lo ometta per mantenerlo; null/vuoto lo cancella.

Modello: ^[^<>]*$
event_date
string <date> | null

Nuovo giorno dell'evento, YYYY-MM-DD. Lo ometta per mantenerlo; null lo cancella.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4521
title
string

Titolo della voce. Testo semplice.

Esempio: "Első tárgyalás elhalasztva"
description
string | null

Dettagli della voce come HTML formattato, sanificato lato server.

location
string | null

Dove è avvenuto (testo semplice), ad es. un'aula di tribunale; può essere null.

event_date
string <date> | null

Giorno della voce, YYYY-MM-DD. Flowyer registra solo la data, non l'ora del giorno.

user_id
integer | null

Autore (l'utente che ha creato la voce).

created_by
string | null

Nome visualizzato dell'autore.

last_editor_id
integer | null

Utente che ha modificato per ultimo la voce.

last_editor
string | null

Nome visualizzato dell'ultimo editor.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a litigation.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/litigation/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "title": "Ítélethirdetés elhalasztva"
}'

Esempi di risposta

{
  "data": {
    "id": 4521,
    "title": "Első tárgyalás elhalasztva",
    "description": "string",
    "location": "string",
    "event_date": "2026-10-30",
    "user_id": 1234,
    "created_by": "string",
    "last_editor_id": 1234,
    "last_editor": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Registro postale

Elenca il registro postale

GET /api/agent/mail-register

Elenca le voci del registro postale (Postakönyv) archiviate sulle pratiche che l'utente può vedere, prima le più recenti. Filtra per pratica, direzione, testo libero (oggetto/mittente/destinatario/numero di tracciamento) e intervallo di date. La posta delle pratiche archiviate è nascosta a meno che include_archived non sia true.

Ambito
mail_register:read
Permesso Flowyer
mail:read

Parametri di query

matter_id
integer>= 1

Solo le voci di questa pratica (deve essere visibile all'utente).

Esempio: 1234
direction
string

Solo le voci in entrata (ricevute) o in uscita (inviate).

Valori ammessi: "incoming" "outgoing"
q
stringal massimo 100 caratteri

Ricerca a testo libero su oggetto, mittente, destinatario, ricevente e numero di tracciamento (maiuscole/minuscole ignorate).

Esempio: "Kúria"
date_from
string <date>

Solo le voci la cui data è a partire da questo giorno incluso (YYYY-MM-DD).

Esempio: "2026-01-01"
date_to
string <date>

Solo le voci la cui data è fino a questo giorno incluso (YYYY-MM-DD).

Esempio: "2026-12-31"
updated_since
string <date-time>

Solo le voci modificate a partire da questo momento (ISO 8601).

Esempio: "2026-10-01T00:00:00+02:00"
include_archived
boolean

Includi le voci delle pratiche archiviate.

Predefinito: false
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id della voce del registro postale (da usare con mail_register.get / .update).

Esempio: 4321
matter
object | null

La pratica su cui è archiviata la voce.

Campi di matter
id
integer
case_number
string
direction
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

subject
string | null
sender
string | null

Feladó: il mittente (testo libero).

to
string | null

Címzett: il destinatario (testo libero).

recipient
string | null

Per una posta in entrata: il nome visualizzato del collega che l'ha ricevuta. Per una posta in uscita: il destinatario/ricevuto da a testo libero.

recipient_user_id
integer | null

Impostato solo per una posta in entrata il cui destinatario è un collega (un id utente); null per una posta in uscita.

electronic
boolean

True quando l'elemento è stato registrato come elettronico (type_of_mail).

delivery_method_id
integer | null

Id del metodo di consegna (mail_delivery_methods).

delivery_method
string | null

Etichetta localizzata del metodo di consegna (Posta, Cégkapu, Perkapu, ...), oppure il fallback elettronico/non elettronico per una riga legacy.

tracking_no
string | null

Azonosító: numero di tracciamento.

folder_path
string | null
recorded_by_user_id
integer | null

Il collega che ha registrato la voce.

recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a mail_register.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/mail-register?matter_id=1234&q=K%C3%BAria&date_from=2026-01-01' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 4321,
      "matter": {
        "id": 1234,
        "case_number": "string"
      },
      "direction": "incoming",
      "date": "2026-10-30",
      "subject": "string",
      "sender": "string",
      "to": "string",
      "recipient": "string",
      "recipient_user_id": 1234,
      "electronic": true,
      "delivery_method_id": 1234,
      "delivery_method": "string",
      "tracking_no": "string",
      "folder_path": "string",
      "recorded_by_user_id": 1234,
      "recorded_by": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni la voce del registro postale

GET /api/agent/mail-register/{id}

Restituisce una voce del registro postale (Postakönyv) per id, con il suo updated_at (il token che mail_register.update accetta). Risponde 404 quando la voce non esiste o la sua pratica non è visibile all'utente.

Ambito
mail_register:read
Permesso Flowyer
mail:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della voce del registro postale.

Esempio: 4321

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id della voce del registro postale (da usare con mail_register.get / .update).

Esempio: 4321
matter
object | null

La pratica su cui è archiviata la voce.

Campi di matter
id
integer
case_number
string
direction
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

subject
string | null
sender
string | null

Feladó: il mittente (testo libero).

to
string | null

Címzett: il destinatario (testo libero).

recipient
string | null

Per una posta in entrata: il nome visualizzato del collega che l'ha ricevuta. Per una posta in uscita: il destinatario/ricevuto da a testo libero.

recipient_user_id
integer | null

Impostato solo per una posta in entrata il cui destinatario è un collega (un id utente); null per una posta in uscita.

electronic
boolean

True quando l'elemento è stato registrato come elettronico (type_of_mail).

delivery_method_id
integer | null

Id del metodo di consegna (mail_delivery_methods).

delivery_method
string | null

Etichetta localizzata del metodo di consegna (Posta, Cégkapu, Perkapu, ...), oppure il fallback elettronico/non elettronico per una riga legacy.

tracking_no
string | null

Azonosító: numero di tracciamento.

folder_path
string | null
recorded_by_user_id
integer | null

Il collega che ha registrato la voce.

recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a mail_register.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/mail-register/4321' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "direction": "incoming",
    "date": "2026-10-30",
    "subject": "string",
    "sender": "string",
    "to": "string",
    "recipient": "string",
    "recipient_user_id": 1234,
    "electronic": true,
    "delivery_method_id": 1234,
    "delivery_method": "string",
    "tracking_no": "string",
    "folder_path": "string",
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Crea una voce del registro postale

POST /api/agent/mail-register

Archivia una nuova voce del registro postale (Postakönyv) su una pratica. Usi recipient_user_id per una posta in entrata ricevuta da un collega, oppure recipient (testo libero) per una in uscita. delivery_method_id deve essere un metodo noto. Risponde 404 quando la pratica non è visibile.

Ambito
mail_register:create
Permesso Flowyer
mail:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

matter_idobbligatorio
integer>= 1

Pratica a cui appartiene la voce (deve essere visibile).

Esempio: 1234
directionobbligatorio
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
dateobbligatorio
string <date>

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

Esempio: "2026-11-03"
subjectobbligatorio
stringalmeno 1 caratterial massimo 1000 caratteri

Oggetto della corrispondenza. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Fellebbezés a Kúriához"
sender
string | nullal massimo 1000 caratteri

Feladó: il mittente (testo libero). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
to
string | nullal massimo 1000 caratteri

Címzett: il destinatario (testo libero). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
recipient
string | nullal massimo 1000 caratteri

Posta in uscita: il destinatario/ricevuto da a testo libero. Non consentito insieme a recipient_user_id. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
recipient_user_id
integer | null>= 1

Posta in entrata: il collega che l'ha ricevuta (un id utente da colleagues.list), memorizzato come destinatario numerico. Non consentito insieme a recipient.

electronic
boolean

Se l'elemento è elettronico (type_of_mail); indipendente dal metodo di consegna. Predefinito false.

Predefinito: false
delivery_method_id
integer | null>= 1

Id del metodo di consegna (mail_delivery_methods): ad es. 1 Posta, 4 Cégkapu, 7 Perkapu. 422 quando sconosciuto.

tracking_no
string | nullal massimo 255 caratteri

Azonosító: numero di tracciamento. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
folder_path
string | nullal massimo 1000 caratteri
Modello: ^[^<>]*$
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce del registro postale (da usare con mail_register.get / .update).

Esempio: 4321
matter
object | null

La pratica su cui è archiviata la voce.

Campi di matter
id
integer
case_number
string
direction
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

subject
string | null
sender
string | null

Feladó: il mittente (testo libero).

to
string | null

Címzett: il destinatario (testo libero).

recipient
string | null

Per una posta in entrata: il nome visualizzato del collega che l'ha ricevuta. Per una posta in uscita: il destinatario/ricevuto da a testo libero.

recipient_user_id
integer | null

Impostato solo per una posta in entrata il cui destinatario è un collega (un id utente); null per una posta in uscita.

electronic
boolean

True quando l'elemento è stato registrato come elettronico (type_of_mail).

delivery_method_id
integer | null

Id del metodo di consegna (mail_delivery_methods).

delivery_method
string | null

Etichetta localizzata del metodo di consegna (Posta, Cégkapu, Perkapu, ...), oppure il fallback elettronico/non elettronico per una riga legacy.

tracking_no
string | null

Azonosító: numero di tracciamento.

folder_path
string | null
recorded_by_user_id
integer | null

Il collega che ha registrato la voce.

recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a mail_register.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce del registro postale (da usare con mail_register.get / .update).

Esempio: 4321
matter
object | null

La pratica su cui è archiviata la voce.

Campi di matter
id
integer
case_number
string
direction
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

subject
string | null
sender
string | null

Feladó: il mittente (testo libero).

to
string | null

Címzett: il destinatario (testo libero).

recipient
string | null

Per una posta in entrata: il nome visualizzato del collega che l'ha ricevuta. Per una posta in uscita: il destinatario/ricevuto da a testo libero.

recipient_user_id
integer | null

Impostato solo per una posta in entrata il cui destinatario è un collega (un id utente); null per una posta in uscita.

electronic
boolean

True quando l'elemento è stato registrato come elettronico (type_of_mail).

delivery_method_id
integer | null

Id del metodo di consegna (mail_delivery_methods).

delivery_method
string | null

Etichetta localizzata del metodo di consegna (Posta, Cégkapu, Perkapu, ...), oppure il fallback elettronico/non elettronico per una riga legacy.

tracking_no
string | null

Azonosító: numero di tracciamento.

folder_path
string | null
recorded_by_user_id
integer | null

Il collega che ha registrato la voce.

recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a mail_register.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/mail-register' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "matter_id": 1234,
  "direction": "incoming",
  "date": "2026-11-03",
  "subject": "Fellebbezés a Kúriához"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "direction": "incoming",
    "date": "2026-10-30",
    "subject": "string",
    "sender": "string",
    "to": "string",
    "recipient": "string",
    "recipient_user_id": 1234,
    "electronic": true,
    "delivery_method_id": 1234,
    "delivery_method": "string",
    "tracking_no": "string",
    "folder_path": "string",
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna la voce del registro postale

PATCH /api/agent/mail-register/{id}

Aggiorna una voce del registro postale (Postakönyv); vengono modificati solo i campi che invia. La voce rimane sulla sua pratica. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409. Risponde 404 quando la voce non è visibile.

Ambito
mail_register:update
Permesso Flowyer
mail:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

direction
string | null

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD.

subject
string | nullalmeno 1 caratterial massimo 1000 caratteri

Oggetto. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
sender
string | nullal massimo 1000 caratteri

Feladó: il mittente (testo libero). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
to
string | nullal massimo 1000 caratteri

Címzett: il destinatario (testo libero). Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
recipient
string | nullal massimo 1000 caratteri

Posta in uscita: il destinatario a testo libero. Non consentito insieme a recipient_user_id. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
recipient_user_id
integer | null>= 1

Posta in entrata: il collega ricevente (un id utente), memorizzato come destinatario numerico. Non consentito insieme a recipient.

electronic
boolean | null

Se l'elemento è elettronico (type_of_mail).

delivery_method_id
integer | null>= 1

Id del metodo di consegna (mail_delivery_methods); 422 quando sconosciuto.

tracking_no
string | nullal massimo 255 caratteri

Azonosító: numero di tracciamento. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
folder_path
string | nullal massimo 1000 caratteri
Modello: ^[^<>]*$

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id della voce del registro postale (da usare con mail_register.get / .update).

Esempio: 4321
matter
object | null

La pratica su cui è archiviata la voce.

Campi di matter
id
integer
case_number
string
direction
string

incoming = ricevuta, outgoing = inviata.

Valori ammessi: "incoming" "outgoing"
date
string <date> | null

Data postale/di registrazione, YYYY-MM-DD (nessuna ora del giorno).

subject
string | null
sender
string | null

Feladó: il mittente (testo libero).

to
string | null

Címzett: il destinatario (testo libero).

recipient
string | null

Per una posta in entrata: il nome visualizzato del collega che l'ha ricevuta. Per una posta in uscita: il destinatario/ricevuto da a testo libero.

recipient_user_id
integer | null

Impostato solo per una posta in entrata il cui destinatario è un collega (un id utente); null per una posta in uscita.

electronic
boolean

True quando l'elemento è stato registrato come elettronico (type_of_mail).

delivery_method_id
integer | null

Id del metodo di consegna (mail_delivery_methods).

delivery_method
string | null

Etichetta localizzata del metodo di consegna (Posta, Cégkapu, Perkapu, ...), oppure il fallback elettronico/non elettronico per una riga legacy.

tracking_no
string | null

Azonosító: numero di tracciamento.

folder_path
string | null
recorded_by_user_id
integer | null

Il collega che ha registrato la voce.

recorded_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a mail_register.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la voce tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/mail-register/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "direction": "incoming"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "direction": "incoming",
    "date": "2026-10-30",
    "subject": "string",
    "sender": "string",
    "to": "string",
    "recipient": "string",
    "recipient_user_id": 1234,
    "electronic": true,
    "delivery_method_id": 1234,
    "delivery_method": "string",
    "tracking_no": "string",
    "folder_path": "string",
    "recorded_by_user_id": 1234,
    "recorded_by": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Commenti

Elenca i commenti della pratica

GET /api/agent/matters/{id}/comments

Elenca i commenti di una pratica, prima i più vecchi: id, autore, corpo (HTML formattato) e il parent_id di una risposta. Piatto, non annidato - ricostruisca i thread di un solo livello da parent_id. Passi top_level_only per escludere le risposte. Risponde 404 quando la pratica non è visibile all'utente.

Ambito
comments:read
Permesso Flowyer
cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica (deve essere visibile).

Esempio: 1234

Parametri di query

top_level_only
boolean

Solo i commenti di primo livello (escludi le risposte). Predefinito false.

Predefinito: false
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 9876
matter_id
integer

La pratica (= case_id) a cui appartiene il commento.

parent_id
integer | null

Il commento di primo livello a cui questo risponde; null per un commento di primo livello. Le risposte sono di un solo livello di profondità.

author_user_id
integer | null

Id utente dell'autore (null per un'importazione legacy).

author_name
string | null

Nome visualizzato dell'autore, oppure null.

body
string

Il commento come memorizzato: HTML formattato, già ripulito con HTMLPurifier per i commenti scritti tramite questa API.

created_at
string <date-time> | null

Quando il commento è stato pubblicato, ISO 8601 nel fuso dello studio.

updated_at
string <date-time> | null

Token di blocco ottimistico: lo passi a comments.update come expected_updated_at. Non è un orario di visualizzazione; null per un commento legacy che non ne ha uno.

edited
boolean

True quando il commento è stato modificato dopo la pubblicazione.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/comments?limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 9876,
      "matter_id": 1234,
      "parent_id": 1234,
      "author_user_id": 1234,
      "author_name": "string",
      "body": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "edited": true
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Pubblica un commento della pratica

POST /api/agent/matters/{id}/comments

Pubblica un commento su una pratica, oppure una risposta di un solo livello (parent_id = un commento di PRIMO LIVELLO della STESSA pratica). Il corpo è HTML formattato, sanificato lato server prima della memorizzazione. Risponde 404 quando la pratica non è visibile, 422 quando parent_id non è un commento di primo livello della pratica.

Ambito
comments:create
Permesso Flowyer
cases:create

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica (deve essere visibile).

Esempio: 1234

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

bodyobbligatorio
stringalmeno 1 caratteri

Il commento, HTML formattato (come lo produce TinyMCE). Ripulito lato server con HTMLPurifier prima della memorizzazione. Al massimo 100000 caratteri.

Esempio: "<p>Egyetértek, a határidő tartható.</p>"
parent_id
integer | null>= 1

Rispondi a questo commento di PRIMO LIVELLO della STESSA pratica (da comments.list, parent_id = null); ometta per un nuovo commento di primo livello.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
matter_id
integer

La pratica (= case_id) a cui appartiene il commento.

parent_id
integer | null

Il commento di primo livello a cui questo risponde; null per un commento di primo livello. Le risposte sono di un solo livello di profondità.

author_user_id
integer | null

Id utente dell'autore (null per un'importazione legacy).

author_name
string | null

Nome visualizzato dell'autore, oppure null.

body
string

Il commento come memorizzato: HTML formattato, già ripulito con HTMLPurifier per i commenti scritti tramite questa API.

created_at
string <date-time> | null

Quando il commento è stato pubblicato, ISO 8601 nel fuso dello studio.

updated_at
string <date-time> | null

Token di blocco ottimistico: lo passi a comments.update come expected_updated_at. Non è un orario di visualizzazione; null per un commento legacy che non ne ha uno.

edited
boolean

True quando il commento è stato modificato dopo la pubblicazione.

created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
matter_id
integer

La pratica (= case_id) a cui appartiene il commento.

parent_id
integer | null

Il commento di primo livello a cui questo risponde; null per un commento di primo livello. Le risposte sono di un solo livello di profondità.

author_user_id
integer | null

Id utente dell'autore (null per un'importazione legacy).

author_name
string | null

Nome visualizzato dell'autore, oppure null.

body
string

Il commento come memorizzato: HTML formattato, già ripulito con HTMLPurifier per i commenti scritti tramite questa API.

created_at
string <date-time> | null

Quando il commento è stato pubblicato, ISO 8601 nel fuso dello studio.

updated_at
string <date-time> | null

Token di blocco ottimistico: lo passi a comments.update come expected_updated_at. Non è un orario di visualizzazione; null per un commento legacy che non ne ha uno.

edited
boolean

True quando il commento è stato modificato dopo la pubblicazione.

created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/comments' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "body": "<p>Egyetértek, a határidő tartható.</p>"
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "matter_id": 1234,
    "parent_id": 1234,
    "author_user_id": 1234,
    "author_name": "string",
    "body": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "edited": true
  },
  "created": true
}

Modifica un proprio commento della pratica

PATCH /api/agent/comments/{id}

Modifica uno dei SUOI commenti (solo il suo corpo; HTML formattato, sanificato lato server prima della memorizzazione). Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409. Risponde 404 per un commento che non è suo o su una pratica che non può vedere.

Ambito
comments:update
Permesso Flowyer
cases:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

bodyobbligatorio
stringalmeno 1 caratteri

Nuovo corpo del commento, HTML formattato (come lo produce TinyMCE). Ripulito lato server con HTMLPurifier prima della memorizzazione. Al massimo 100000 caratteri.

Esempio: "<p>Pontosítás: a határidő november 15.</p>"

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 9876
matter_id
integer

La pratica (= case_id) a cui appartiene il commento.

parent_id
integer | null

Il commento di primo livello a cui questo risponde; null per un commento di primo livello. Le risposte sono di un solo livello di profondità.

author_user_id
integer | null

Id utente dell'autore (null per un'importazione legacy).

author_name
string | null

Nome visualizzato dell'autore, oppure null.

body
string

Il commento come memorizzato: HTML formattato, già ripulito con HTMLPurifier per i commenti scritti tramite questa API.

created_at
string <date-time> | null

Quando il commento è stato pubblicato, ISO 8601 nel fuso dello studio.

updated_at
string <date-time> | null

Token di blocco ottimistico: lo passi a comments.update come expected_updated_at. Non è un orario di visualizzazione; null per un commento legacy che non ne ha uno.

edited
boolean

True quando il commento è stato modificato dopo la pubblicazione.

updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/comments/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "body": "<p>Pontosítás: a határidő november 15.</p>"
}'

Esempi di risposta

{
  "data": {
    "id": 9876,
    "matter_id": 1234,
    "parent_id": 1234,
    "author_user_id": 1234,
    "author_name": "string",
    "body": "string",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "edited": true
  },
  "updated": true
}

Udienze

Elenca le udienze della pratica

GET /api/agent/matters/{id}/trials

Elenca le udienze (tárgyalások) di una pratica: data, tribunale, luogo, i colleghi presenti e il giudice, prima le più recenti. Facoltativamente filtrate per un intervallo di giorni da/a o per updated_since. Risponde 404 quando la pratica non è visibile all'utente.

Ambito
trials:read
Permesso Flowyer
trials:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della pratica.

Esempio: 1234

Parametri di query

from
string <date>

Solo le udienze a partire da questo giorno incluso (YYYY-MM-DD), nel fuso orario dello studio.

Esempio: "2026-01-01"
to
string <date>

Solo le udienze fino a questo giorno incluso (YYYY-MM-DD), nel fuso orario dello studio.

Esempio: "2026-12-31"
updated_since
string <date-time>

Solo le udienze modificate a partire da questo momento ISO 8601.

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 4321
matter
object

La pratica (causa) a cui appartiene l'udienza.

Campi di matter
id
integer
case_number
string
date
string <date-time> | null

Data e ora dell'udienza, ISO 8601 nel fuso orario dello studio. È memorizzata in UTC, quindi confronti gli istanti invece del testo dell'ora di parete.

Esempio: "2026-03-02T09:00:00+01:00"
participation
string | null

Se è richiesta la presenza di un collega: "required", "not_required", oppure null quando non impostato.

Valori ammessi: "required" "not_required"
court
object | null

Il tribunale dell'udienza, risolto dal registro condiviso dei tribunali; null quando nessun tribunale è impostato.

Campi di court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Sempre "registry": il tribunale è un riferimento al registro condiviso dei tribunali (courts.list), non testo libero.

place
string | null

Aula o luogo dell'udienza. Testo semplice.

name_of_the_judge
string | null

Nome del giudice. Testo semplice.

notes
string | null

Note a testo libero sull'udienza. Testo semplice.

responsibles
object[]

Colleghi che partecipano all'udienza (id da colleagues.list).

Campi di responsibles
user_id
integer
name
string | null
recorded_by
object | null

Il collega che ha registrato l'udienza.

Campi di recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a trials.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/matters/1234/trials?from=2026-01-01&to=2026-12-31&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 4321,
      "matter": {
        "id": 1234,
        "case_number": "string"
      },
      "date": "2026-03-02T09:00:00+01:00",
      "participation": "required",
      "court": {
        "id": 1234,
        "name": "string",
        "city": "string",
        "zip": "string",
        "address": "string",
        "source": "string"
      },
      "place": "string",
      "name_of_the_judge": "string",
      "notes": "string",
      "responsibles": [
        {
          "user_id": 1234,
          "name": "string"
        }
      ],
      "recorded_by": {
        "user_id": 1234,
        "name": "string"
      },
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni l'udienza

GET /api/agent/trials/{id}

Restituisce un'udienza (tárgyalás) con la sua pratica, il tribunale, i colleghi presenti e il token di blocco updated_at per trials.update. Risponde 404 quando l'udienza non esiste o l'utente non può vedere la sua pratica.

Ambito
trials:read
Permesso Flowyer
trials:read

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'udienza.

Esempio: 4321

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
matter
object

La pratica (causa) a cui appartiene l'udienza.

Campi di matter
id
integer
case_number
string
date
string <date-time> | null

Data e ora dell'udienza, ISO 8601 nel fuso orario dello studio. È memorizzata in UTC, quindi confronti gli istanti invece del testo dell'ora di parete.

Esempio: "2026-03-02T09:00:00+01:00"
participation
string | null

Se è richiesta la presenza di un collega: "required", "not_required", oppure null quando non impostato.

Valori ammessi: "required" "not_required"
court
object | null

Il tribunale dell'udienza, risolto dal registro condiviso dei tribunali; null quando nessun tribunale è impostato.

Campi di court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Sempre "registry": il tribunale è un riferimento al registro condiviso dei tribunali (courts.list), non testo libero.

place
string | null

Aula o luogo dell'udienza. Testo semplice.

name_of_the_judge
string | null

Nome del giudice. Testo semplice.

notes
string | null

Note a testo libero sull'udienza. Testo semplice.

responsibles
object[]

Colleghi che partecipano all'udienza (id da colleagues.list).

Campi di responsibles
user_id
integer
name
string | null
recorded_by
object | null

Il collega che ha registrato l'udienza.

Campi di recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a trials.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/trials/4321' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "date": "2026-03-02T09:00:00+01:00",
    "participation": "required",
    "court": {
      "id": 1234,
      "name": "string",
      "city": "string",
      "zip": "string",
      "address": "string",
      "source": "string"
    },
    "place": "string",
    "name_of_the_judge": "string",
    "notes": "string",
    "responsibles": [
      {
        "user_id": 1234,
        "name": "string"
      }
    ],
    "recorded_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Crea un'udienza

POST /api/agent/matters/{id}/trials

Registra un'udienza (tárgyalás) su una pratica: ora, un tribunale facoltativo (court_id da courts.list), l'aula, il giudice, le note e i colleghi presenti. La pratica deve essere visibile e non archiviata; i partecipanti vengono notificati. Un orario senza offset viene letto nel fuso dello studio.

Ambito
trials:create
Permesso Flowyer
trials:create

Parametri di percorso

idobbligatorio
integer>= 1

Pratica a cui appartiene l'udienza (deve essere visibile e non archiviata).

Esempio: 1234

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

dateobbligatorio
string <date-time>

Data e ora dell'udienza, ISO 8601. Con un offset viene rispettato; senza, viene letto nel fuso orario dello studio. Memorizzato in UTC.

Esempio: "2026-03-02T09:00:00+01:00"
court_id
integer | null>= 1

Tribunale dell'udienza: un id da courts.list (il registro condiviso dei tribunali). Ometta quando il tribunale non è noto.

Esempio: 42
participation
string | null

Se è richiesta la presenza di un collega. Ometta per lasciarla non impostata.

Valori ammessi: "required" "not_required"
place
string | nullal massimo 1000 caratteri

Aula o luogo dell'udienza. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "II. emelet 205."
name_of_the_judge
string | nullal massimo 255 caratteri

Nome del giudice. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
notes
string | nullal massimo 10000 caratteri

Note a testo libero sull'udienza. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
responsible_user_ids
integer[] | null

Id utente dei colleghi (da colleagues.list) che partecipano all'udienza.

idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
matter
object

La pratica (causa) a cui appartiene l'udienza.

Campi di matter
id
integer
case_number
string
date
string <date-time> | null

Data e ora dell'udienza, ISO 8601 nel fuso orario dello studio. È memorizzata in UTC, quindi confronti gli istanti invece del testo dell'ora di parete.

Esempio: "2026-03-02T09:00:00+01:00"
participation
string | null

Se è richiesta la presenza di un collega: "required", "not_required", oppure null quando non impostato.

Valori ammessi: "required" "not_required"
court
object | null

Il tribunale dell'udienza, risolto dal registro condiviso dei tribunali; null quando nessun tribunale è impostato.

Campi di court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Sempre "registry": il tribunale è un riferimento al registro condiviso dei tribunali (courts.list), non testo libero.

place
string | null

Aula o luogo dell'udienza. Testo semplice.

name_of_the_judge
string | null

Nome del giudice. Testo semplice.

notes
string | null

Note a testo libero sull'udienza. Testo semplice.

responsibles
object[]

Colleghi che partecipano all'udienza (id da colleagues.list).

Campi di responsibles
user_id
integer
name
string | null
recorded_by
object | null

Il collega che ha registrato l'udienza.

Campi di recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a trials.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
matter
object

La pratica (causa) a cui appartiene l'udienza.

Campi di matter
id
integer
case_number
string
date
string <date-time> | null

Data e ora dell'udienza, ISO 8601 nel fuso orario dello studio. È memorizzata in UTC, quindi confronti gli istanti invece del testo dell'ora di parete.

Esempio: "2026-03-02T09:00:00+01:00"
participation
string | null

Se è richiesta la presenza di un collega: "required", "not_required", oppure null quando non impostato.

Valori ammessi: "required" "not_required"
court
object | null

Il tribunale dell'udienza, risolto dal registro condiviso dei tribunali; null quando nessun tribunale è impostato.

Campi di court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Sempre "registry": il tribunale è un riferimento al registro condiviso dei tribunali (courts.list), non testo libero.

place
string | null

Aula o luogo dell'udienza. Testo semplice.

name_of_the_judge
string | null

Nome del giudice. Testo semplice.

notes
string | null

Note a testo libero sull'udienza. Testo semplice.

responsibles
object[]

Colleghi che partecipano all'udienza (id da colleagues.list).

Campi di responsibles
user_id
integer
name
string | null
recorded_by
object | null

Il collega che ha registrato l'udienza.

Campi di recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a trials.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/matters/1234/trials' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "date": "2026-03-02T09:00:00+01:00",
  "court_id": 42,
  "place": "II. emelet 205."
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "date": "2026-03-02T09:00:00+01:00",
    "participation": "required",
    "court": {
      "id": 1234,
      "name": "string",
      "city": "string",
      "zip": "string",
      "address": "string",
      "source": "string"
    },
    "place": "string",
    "name_of_the_judge": "string",
    "notes": "string",
    "responsibles": [
      {
        "user_id": 1234,
        "name": "string"
      }
    ],
    "recorded_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna l'udienza

PATCH /api/agent/trials/{id}

Aggiorna un'udienza (tárgyalás): la sua ora, il tribunale, il luogo, il giudice, le note, il flag di presenza e i partecipanti. Scrive solo i campi che invia; invii responsible_user_ids per sostituire l'intero elenco dei partecipanti. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409.

Ambito
trials:update
Permesso Flowyer
trials:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

date
string <date-time>

Nuova data e ora dell'udienza, ISO 8601 (un offset viene rispettato, un'ora naive viene letta nel fuso dello studio). Memorizzato in UTC.

Esempio: "2026-03-02T09:00:00+01:00"
court_id
integer | null>= 1

Nuovo id del tribunale da courts.list; null per cancellare il tribunale.

participation
string | null

Se è richiesta la presenza di un collega; null per cancellarla.

Valori ammessi: "required" "not_required"
place
string | nullal massimo 1000 caratteri

Aula o luogo. Testo semplice; "<" e ">" non sono consentiti. "" lo cancella.

Modello: ^[^<>]*$
name_of_the_judge
string | nullal massimo 255 caratteri

Nome del giudice. Testo semplice; "<" e ">" non sono consentiti. "" lo cancella.

Modello: ^[^<>]*$
notes
string | nullal massimo 10000 caratteri

Note a testo libero. Testo semplice; "<" e ">" non sono consentiti. "" le cancella.

Modello: ^[^<>]*$
responsible_user_ids
integer[] | null

Insieme completo sostitutivo di id utente dei partecipanti (da colleagues.list). Ometta per lasciare invariati i partecipanti.

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
matter
object

La pratica (causa) a cui appartiene l'udienza.

Campi di matter
id
integer
case_number
string
date
string <date-time> | null

Data e ora dell'udienza, ISO 8601 nel fuso orario dello studio. È memorizzata in UTC, quindi confronti gli istanti invece del testo dell'ora di parete.

Esempio: "2026-03-02T09:00:00+01:00"
participation
string | null

Se è richiesta la presenza di un collega: "required", "not_required", oppure null quando non impostato.

Valori ammessi: "required" "not_required"
court
object | null

Il tribunale dell'udienza, risolto dal registro condiviso dei tribunali; null quando nessun tribunale è impostato.

Campi di court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Sempre "registry": il tribunale è un riferimento al registro condiviso dei tribunali (courts.list), non testo libero.

place
string | null

Aula o luogo dell'udienza. Testo semplice.

name_of_the_judge
string | null

Nome del giudice. Testo semplice.

notes
string | null

Note a testo libero sull'udienza. Testo semplice.

responsibles
object[]

Colleghi che partecipano all'udienza (id da colleagues.list).

Campi di responsibles
user_id
integer
name
string | null
recorded_by
object | null

Il collega che ha registrato l'udienza.

Campi di recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a trials.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/trials/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "date": "2026-03-02T09:00:00+01:00"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "date": "2026-03-02T09:00:00+01:00",
    "participation": "required",
    "court": {
      "id": 1234,
      "name": "string",
      "city": "string",
      "zip": "string",
      "address": "string",
      "source": "string"
    },
    "place": "string",
    "name_of_the_judge": "string",
    "notes": "string",
    "responsibles": [
      {
        "user_id": 1234,
        "name": "string"
      }
    ],
    "recorded_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Tribunali

Elenca i tribunali

GET /api/agent/courts

Elenca il registro condiviso dei tribunali (id, nome, città) per il court_id di trials.create / trials.update. Con q (un nome di tribunale così come ascoltato; accenti, maiuscole/minuscole e piccoli errori di battitura tollerati) risponde con lo stato exact/similar/none: solo "exact" è sicuro da usare direttamente. È l'elenco dei tribunali ungheresi.

Ambito
courts:read

Parametri di query

q
stringal massimo 255 caratteri

Un nome di tribunale da cercare, così come ascoltato o dettato, in qualsiasi ordine delle parole. Lo ometta per elencare tutti i tribunali.

Esempio: "Fővárosi Törvényszék"
limit
integer>= 1<= 500

Numero massimo di tribunali da restituire (predefinito 200).

Predefinito: 200

Risposte

200

OK.

dataobbligatorio
object
Campi di data
status
string | null

Solo con q: exact = una corrispondenza certa (sicuro usare il suo id), similar = corrispondenza approssimativa o più corrispondenze (prima confermi con l'utente), none = nessuna corrispondenza (chieda all'utente). Null senza q.

Valori ammessi: "exact" "similar" "none"
courts
object[]

Tribunali, prima la corrispondenza migliore con q, altrimenti per nome.

Campi di courts
id
integer

Id del tribunale: lo passi come court_id a trials.create / trials.update.

name
string

Nome del tribunale come mostrato in Flowyer.

city
string | null
zip
string | null
address
string | null
total
integer

Quanti tribunali hanno corrisposto (tutti i tribunali senza q) prima che l'elenco fosse ridotto a limit.

truncated
boolean

True quando hanno corrisposto più tribunali di quanti ne siano stati restituiti: restringa q o aumenti limit.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/courts?q=F%C5%91v%C3%A1rosi%20T%C3%B6rv%C3%A9nysz%C3%A9k' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "status": "exact",
    "courts": [
      {
        "id": 1234,
        "name": "string",
        "city": "string",
        "zip": "string",
        "address": "string"
      }
    ],
    "total": 1,
    "truncated": true
  }
}

HR

Elenca le assenze del personale

GET /api/agent/hr/leaves

Elenca le assenze approvate del personale (chi è o sarà in assenza): il collega, le date di inizio/fine, il conteggio dei giorni lavorativi, una categoria oscurata per privacy (leave/unpaid; sick è unito a leave e mai identificabile) ed eventuali sostituti. Non restituisce mai il tipo di assenza, le note o chi l'ha approvata.

Ambito
hr:read
Permesso Flowyer
hr-admin:read

Parametri di query

user_id
integer>= 1

Solo le assenze di questo collega. Un id utente centrale (da colleagues.list), associato al dipendente dietro l'assenza.

Esempio: 1234
on_date
string <date>

Chi è in assenza in questo giorno esatto (start_date <= on_date <= end_date). Quando è impostato, ha la precedenza su date_from, date_to e timeframe.

date_from
string <date>

Solo le assenze ancora in corso a partire da questa data inclusa (end_date >= date_from). Il valore predefinito è oggi, quindi le assenze interamente passate sono escluse per impostazione predefinita.

date_to
string <date>

Solo le assenze che iniziano entro questa data inclusa (start_date <= date_to). Ometta per un futuro senza limiti.

timeframe
string

Vincolo aggiuntivo sulla data di inizio rispetto a oggi: current = già iniziate (in corso), upcoming = non ancora iniziate, all = nessun vincolo aggiuntivo. Ignorato quando on_date è impostato.

Valori ammessi: "current" "upcoming" "all"
Predefinito: "all"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id della richiesta di assenza (solo un identificatore; non sensibile).

user_id
integer

Il collega in assenza (id utente centrale).

user
string | null

Il nome visualizzato del collega.

start_date
string <date>

Primo giorno di assenza (YYYY-MM-DD).

end_date
string <date>

Ultimo giorno di assenza, incluso (YYYY-MM-DD).

days_count
number | null

Giorni lavorativi di assenza. Non rivela il tipo.

category
string

Tipo di assenza oscurato per privacy: sia annual che sick diventano "leave" (sick non è mai identificabile), unpaid rimane "unpaid". Il tipo di assenza grezzo non viene mai esposto.

Valori ammessi: "leave" "unpaid"
status
string

Sempre "approved" - vengono restituite solo le assenze approvate; pending, rejected e cancelled non compaiono mai.

Valori ammessi: "approved"
substitute_user_id
integer | null

Collega sostituto per questa assenza (id utente centrale), oppure null.

substitute_user
string | null

Nome visualizzato del collega sostituto, oppure null.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/hr/leaves?user_id=1234&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 1234,
      "user_id": 1234,
      "user": "string",
      "start_date": "2026-10-30",
      "end_date": "2026-10-30",
      "days_count": 0,
      "category": "leave",
      "status": "approved",
      "substitute_user_id": 1234,
      "substitute_user": "string"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Calendario

Elenca gli eventi del calendario

GET /api/agent/calendar/events

Elenca gli eventi del calendario che si sovrappongono a un intervallo di date [from, to]: il calendario dello studio, il suo e i calendari condivisi con Lei. Gli eventi ricorrenti vengono restituiti una sola volta (is_recurring), NON espansi. Ordinati per inizio. Un evento personale non condiviso con Lei non appare mai.

Ambito
calendar:read
Permesso Flowyer
calendar-office:read

Parametri di query

fromobbligatorio
string <date-time>

Inizio dell'intervallo (incluso), ISO 8601. Vengono restituiti gli eventi che si sovrappongono a [from, to]. Un orario senza offset viene letto nel fuso dello studio.

Esempio: "2026-03-01T00:00:00+01:00"
toobbligatorio
string <date-time>

Fine dell'intervallo (inclusa), ISO 8601. Deve essere pari o successiva a from (altrimenti 422) e al massimo 366 giorni dopo.

Esempio: "2026-03-31T23:59:59+01:00"
calendar_ids
integer[]

Restringe a questi id di calendari contenitore; ciascuno viene intersecato con i calendari che Lei può visualizzare, quindi un id che non può vedere viene scartato silenziosamente. Ometta per tutti i calendari visibili.

include_recurring
boolean

Includi gli eventi master ricorrenti la cui regola si sovrappone all'intervallo (restituiti non espansi, is_recurring = true). Predefinito true.

Predefinito: true
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 5501
calendar
object

Il calendario a cui appartiene l'evento.

Campi di calendar
id
integer | null

Id del calendario contenitore, oppure null per il calendario condiviso dello studio implicito (un evento legacy senza contenitore).

name
string | null
type
string

"office" = il calendario condiviso dello studio (ogni utente dello studio può visualizzarlo e modificarlo); "personal" = il calendario personale di un utente, visibile solo al suo proprietario e a coloro con cui è condiviso.

Valori ammessi: "office" "personal"
owner
object | null

Proprietario di un calendario personale; null per il calendario dello studio.

Campi di owner
user_id
integer
name
string | null
title
string | null

Titolo dell'evento. Testo semplice.

description
string | null

Descrizione dell'evento. Testo semplice.

location
string | null

Luogo. Testo semplice.

participants
string | null

Partecipanti, testo libero. Testo semplice.

start
string | null

Un evento per tutto il giorno: la data di inizio "YYYY-MM-DD". Un evento con orario: ISO 8601 nel fuso orario dello studio (l'istante UTC memorizzato).

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Per un evento per tutto il giorno la data di fine è INCLUSIVA (il valore memorizzato, non il valore +1 giorno che usa una griglia di calendario). Null quando l'evento non ha una fine.

all_day
boolean

True per un evento per tutto il giorno (start/end sono date semplici); false per un evento con orario (start/end sono istanti ISO 8601).

color
string | null

Colore di visualizzazione, ad es. "#2c7be5".

is_recurring
boolean

True quando l'evento è un master ricorrente. Gli eventi ricorrenti vengono restituiti una sola volta, NON espansi in occorrenze, e non possono essere modificati tramite calendar.events.update.

recurrence
object | null

La regola di ricorrenza di un master ricorrente, oppure null per un evento singolo. Di sola lettura.

Campi di recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Codici dei giorni della settimana separati da virgola (ad es. "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Il collega che ha creato l'evento.

Campi di created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a calendar.events.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/calendar/events?from=2026-03-01T00%3A00%3A00%2B01%3A00&to=2026-03-31T23%3A59%3A59%2B01%3A00&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 5501,
      "calendar": {
        "id": 1234,
        "name": "string",
        "type": "office",
        "owner": {
          "user_id": 1234,
          "name": "string"
        }
      },
      "title": "string",
      "description": "string",
      "location": "string",
      "participants": "string",
      "start": "2026-03-02T09:00:00+01:00",
      "end": "string",
      "all_day": true,
      "color": "string",
      "is_recurring": true,
      "recurrence": {
        "freq": "string",
        "interval": 0,
        "byweekday": "string",
        "until": "string",
        "count": 0
      },
      "created_by": {
        "user_id": 1234,
        "name": "string"
      },
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni l'evento del calendario

GET /api/agent/calendar/events/{id}

Restituisce un evento del calendario con il suo calendario, il riepilogo della ricorrenza e il token di blocco updated_at per calendar.events.update. Risponde 404 quando l'evento non esiste o il suo calendario non è visibile all'utente.

Ambito
calendar:read
Permesso Flowyer
calendar-office:read

Parametri di percorso

idobbligatorio
integer>= 1

Id dell'evento.

Esempio: 5501

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 5501
calendar
object

Il calendario a cui appartiene l'evento.

Campi di calendar
id
integer | null

Id del calendario contenitore, oppure null per il calendario condiviso dello studio implicito (un evento legacy senza contenitore).

name
string | null
type
string

"office" = il calendario condiviso dello studio (ogni utente dello studio può visualizzarlo e modificarlo); "personal" = il calendario personale di un utente, visibile solo al suo proprietario e a coloro con cui è condiviso.

Valori ammessi: "office" "personal"
owner
object | null

Proprietario di un calendario personale; null per il calendario dello studio.

Campi di owner
user_id
integer
name
string | null
title
string | null

Titolo dell'evento. Testo semplice.

description
string | null

Descrizione dell'evento. Testo semplice.

location
string | null

Luogo. Testo semplice.

participants
string | null

Partecipanti, testo libero. Testo semplice.

start
string | null

Un evento per tutto il giorno: la data di inizio "YYYY-MM-DD". Un evento con orario: ISO 8601 nel fuso orario dello studio (l'istante UTC memorizzato).

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Per un evento per tutto il giorno la data di fine è INCLUSIVA (il valore memorizzato, non il valore +1 giorno che usa una griglia di calendario). Null quando l'evento non ha una fine.

all_day
boolean

True per un evento per tutto il giorno (start/end sono date semplici); false per un evento con orario (start/end sono istanti ISO 8601).

color
string | null

Colore di visualizzazione, ad es. "#2c7be5".

is_recurring
boolean

True quando l'evento è un master ricorrente. Gli eventi ricorrenti vengono restituiti una sola volta, NON espansi in occorrenze, e non possono essere modificati tramite calendar.events.update.

recurrence
object | null

La regola di ricorrenza di un master ricorrente, oppure null per un evento singolo. Di sola lettura.

Campi di recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Codici dei giorni della settimana separati da virgola (ad es. "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Il collega che ha creato l'evento.

Campi di created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a calendar.events.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/calendar/events/5501' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 5501,
    "calendar": {
      "id": 1234,
      "name": "string",
      "type": "office",
      "owner": {
        "user_id": 1234,
        "name": "string"
      }
    },
    "title": "string",
    "description": "string",
    "location": "string",
    "participants": "string",
    "start": "2026-03-02T09:00:00+01:00",
    "end": "string",
    "all_day": true,
    "color": "string",
    "is_recurring": true,
    "recurrence": {
      "freq": "string",
      "interval": 0,
      "byweekday": "string",
      "until": "string",
      "count": 0
    },
    "created_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Crea un evento del calendario

POST /api/agent/calendar/events

Crea un singolo evento del calendario (con orario o per tutto il giorno) sul calendario dello studio o su un calendario che Lei può modificare. Un inizio/fine con orario rispetta un offset ISO 8601, un'ora naive viene letta nel fuso dello studio; una data di fine per tutto il giorno è inclusiva. Gli eventi ricorrenti non vengono creati qui. Non vengono inviati ai calendari esterni.

Ambito
calendar:create
Permesso Flowyer
calendar-office:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

titleobbligatorio
stringalmeno 1 caratterial massimo 255 caratteri

Titolo dell'evento. Testo semplice; "<" e ">" non sono consentiti (confluisce senza escape nella notifica di promemoria).

Modello: ^[^<>]*$
Esempio: "Ügyfél egyeztetés"
startobbligatorio
string

Per tutto il giorno (all_day true): una data "YYYY-MM-DD". Con orario (all_day false): ISO 8601; un offset viene rispettato, un'ora naive viene letta nel fuso dello studio.

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Predefinito = start. Per un evento per tutto il giorno la data di fine è INCLUSIVA. Non deve essere precedente a start (altrimenti 422).

all_day
boolean

Se l'evento è per tutto il giorno. Predefinito false (con orario).

Predefinito: false
calendar_id
integer | null>= 1

Calendario contenitore di destinazione; predefinito = il calendario dello studio. Deve possedere i diritti di modifica su di esso (altrimenti 403). Solo su un tenant con la funzionalità dei calendari personali.

location
string | nullal massimo 1000 caratteri

Luogo. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
description
string | nullal massimo 10000 caratteri

Descrizione, testo semplice (non HTML); "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
participants
string | nullal massimo 1000 caratteri

Partecipanti, testo libero. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
color
string | nullal massimo 32 caratteri

Colore di visualizzazione, ad es. "#2c7be5".

Modello: ^#?[A-Za-z0-9_-]{1,31}$
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 5501
calendar
object

Il calendario a cui appartiene l'evento.

Campi di calendar
id
integer | null

Id del calendario contenitore, oppure null per il calendario condiviso dello studio implicito (un evento legacy senza contenitore).

name
string | null
type
string

"office" = il calendario condiviso dello studio (ogni utente dello studio può visualizzarlo e modificarlo); "personal" = il calendario personale di un utente, visibile solo al suo proprietario e a coloro con cui è condiviso.

Valori ammessi: "office" "personal"
owner
object | null

Proprietario di un calendario personale; null per il calendario dello studio.

Campi di owner
user_id
integer
name
string | null
title
string | null

Titolo dell'evento. Testo semplice.

description
string | null

Descrizione dell'evento. Testo semplice.

location
string | null

Luogo. Testo semplice.

participants
string | null

Partecipanti, testo libero. Testo semplice.

start
string | null

Un evento per tutto il giorno: la data di inizio "YYYY-MM-DD". Un evento con orario: ISO 8601 nel fuso orario dello studio (l'istante UTC memorizzato).

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Per un evento per tutto il giorno la data di fine è INCLUSIVA (il valore memorizzato, non il valore +1 giorno che usa una griglia di calendario). Null quando l'evento non ha una fine.

all_day
boolean

True per un evento per tutto il giorno (start/end sono date semplici); false per un evento con orario (start/end sono istanti ISO 8601).

color
string | null

Colore di visualizzazione, ad es. "#2c7be5".

is_recurring
boolean

True quando l'evento è un master ricorrente. Gli eventi ricorrenti vengono restituiti una sola volta, NON espansi in occorrenze, e non possono essere modificati tramite calendar.events.update.

recurrence
object | null

La regola di ricorrenza di un master ricorrente, oppure null per un evento singolo. Di sola lettura.

Campi di recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Codici dei giorni della settimana separati da virgola (ad es. "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Il collega che ha creato l'evento.

Campi di created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a calendar.events.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 5501
calendar
object

Il calendario a cui appartiene l'evento.

Campi di calendar
id
integer | null

Id del calendario contenitore, oppure null per il calendario condiviso dello studio implicito (un evento legacy senza contenitore).

name
string | null
type
string

"office" = il calendario condiviso dello studio (ogni utente dello studio può visualizzarlo e modificarlo); "personal" = il calendario personale di un utente, visibile solo al suo proprietario e a coloro con cui è condiviso.

Valori ammessi: "office" "personal"
owner
object | null

Proprietario di un calendario personale; null per il calendario dello studio.

Campi di owner
user_id
integer
name
string | null
title
string | null

Titolo dell'evento. Testo semplice.

description
string | null

Descrizione dell'evento. Testo semplice.

location
string | null

Luogo. Testo semplice.

participants
string | null

Partecipanti, testo libero. Testo semplice.

start
string | null

Un evento per tutto il giorno: la data di inizio "YYYY-MM-DD". Un evento con orario: ISO 8601 nel fuso orario dello studio (l'istante UTC memorizzato).

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Per un evento per tutto il giorno la data di fine è INCLUSIVA (il valore memorizzato, non il valore +1 giorno che usa una griglia di calendario). Null quando l'evento non ha una fine.

all_day
boolean

True per un evento per tutto il giorno (start/end sono date semplici); false per un evento con orario (start/end sono istanti ISO 8601).

color
string | null

Colore di visualizzazione, ad es. "#2c7be5".

is_recurring
boolean

True quando l'evento è un master ricorrente. Gli eventi ricorrenti vengono restituiti una sola volta, NON espansi in occorrenze, e non possono essere modificati tramite calendar.events.update.

recurrence
object | null

La regola di ricorrenza di un master ricorrente, oppure null per un evento singolo. Di sola lettura.

Campi di recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Codici dei giorni della settimana separati da virgola (ad es. "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Il collega che ha creato l'evento.

Campi di created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a calendar.events.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/calendar/events' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "title": "Ügyfél egyeztetés",
  "start": "2026-03-02T09:00:00+01:00"
}'

Esempi di risposta

{
  "data": {
    "id": 5501,
    "calendar": {
      "id": 1234,
      "name": "string",
      "type": "office",
      "owner": {
        "user_id": 1234,
        "name": "string"
      }
    },
    "title": "string",
    "description": "string",
    "location": "string",
    "participants": "string",
    "start": "2026-03-02T09:00:00+01:00",
    "end": "string",
    "all_day": true,
    "color": "string",
    "is_recurring": true,
    "recurrence": {
      "freq": "string",
      "interval": 0,
      "byweekday": "string",
      "until": "string",
      "count": 0
    },
    "created_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna l'evento del calendario

PATCH /api/agent/calendar/events/{id}

Aggiorna un singolo evento del calendario: titolo, start/end, all_day, luogo, descrizione, partecipanti, colore. Scrive solo i campi che invia; "" cancella luogo/descrizione/partecipanti. Un evento ricorrente risponde 422. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409.

Ambito
calendar:update
Permesso Flowyer
calendar-office:modify

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

title
stringalmeno 1 caratterial massimo 255 caratteri

Nuovo titolo. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
start
string

Nuovo inizio. Per tutto il giorno: "YYYY-MM-DD". Con orario: ISO 8601 (un offset viene rispettato, un'ora naive viene letta nel fuso dello studio). Ricodificato se all_day cambia.

end
string | null

Nuova fine, stessa codifica di start; "" la cancella. Per un evento per tutto il giorno la data di fine è inclusiva. Non deve essere precedente a start (altrimenti 422).

all_day
boolean

Se inviato, start/end vengono ricodificati di conseguenza; se omesso, viene usato l'all_day corrente della riga.

location
string | nullal massimo 1000 caratteri

Luogo. Testo semplice; "<" e ">" non sono consentiti. "" lo cancella.

Modello: ^[^<>]*$
description
string | nullal massimo 10000 caratteri

Descrizione, testo semplice (non HTML); "<" e ">" non sono consentiti. "" la cancella.

Modello: ^[^<>]*$
participants
string | nullal massimo 1000 caratteri

Partecipanti, testo libero. Testo semplice; "<" e ">" non sono consentiti. "" li cancella.

Modello: ^[^<>]*$
color
string | nullal massimo 32 caratteri

Colore di visualizzazione, ad es. "#2c7be5". "" lo cancella.

Modello: ^#?[A-Za-z0-9_-]{1,31}$

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 5501
calendar
object

Il calendario a cui appartiene l'evento.

Campi di calendar
id
integer | null

Id del calendario contenitore, oppure null per il calendario condiviso dello studio implicito (un evento legacy senza contenitore).

name
string | null
type
string

"office" = il calendario condiviso dello studio (ogni utente dello studio può visualizzarlo e modificarlo); "personal" = il calendario personale di un utente, visibile solo al suo proprietario e a coloro con cui è condiviso.

Valori ammessi: "office" "personal"
owner
object | null

Proprietario di un calendario personale; null per il calendario dello studio.

Campi di owner
user_id
integer
name
string | null
title
string | null

Titolo dell'evento. Testo semplice.

description
string | null

Descrizione dell'evento. Testo semplice.

location
string | null

Luogo. Testo semplice.

participants
string | null

Partecipanti, testo libero. Testo semplice.

start
string | null

Un evento per tutto il giorno: la data di inizio "YYYY-MM-DD". Un evento con orario: ISO 8601 nel fuso orario dello studio (l'istante UTC memorizzato).

Esempio: "2026-03-02T09:00:00+01:00"
end
string | null

Stessa codifica di start. Per un evento per tutto il giorno la data di fine è INCLUSIVA (il valore memorizzato, non il valore +1 giorno che usa una griglia di calendario). Null quando l'evento non ha una fine.

all_day
boolean

True per un evento per tutto il giorno (start/end sono date semplici); false per un evento con orario (start/end sono istanti ISO 8601).

color
string | null

Colore di visualizzazione, ad es. "#2c7be5".

is_recurring
boolean

True quando l'evento è un master ricorrente. Gli eventi ricorrenti vengono restituiti una sola volta, NON espansi in occorrenze, e non possono essere modificati tramite calendar.events.update.

recurrence
object | null

La regola di ricorrenza di un master ricorrente, oppure null per un evento singolo. Di sola lettura.

Campi di recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Codici dei giorni della settimana separati da virgola (ad es. "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Il collega che ha creato l'evento.

Campi di created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a calendar.events.update come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato il record tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/calendar/events/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "title": "string"
}'

Esempi di risposta

{
  "data": {
    "id": 5501,
    "calendar": {
      "id": 1234,
      "name": "string",
      "type": "office",
      "owner": {
        "user_id": 1234,
        "name": "string"
      }
    },
    "title": "string",
    "description": "string",
    "location": "string",
    "participants": "string",
    "start": "2026-03-02T09:00:00+01:00",
    "end": "string",
    "all_day": true,
    "color": "string",
    "is_recurring": true,
    "recurrence": {
      "freq": "string",
      "interval": 0,
      "byweekday": "string",
      "until": "string",
      "count": 0
    },
    "created_by": {
      "user_id": 1234,
      "name": "string"
    },
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Prenotazioni

Elenca le prenotazioni

GET /api/agent/bookings

Elenca le prenotazioni di appuntamento (időpontfoglalások) dello studio, prima le più recenti. Facoltativamente filtrate per un intervallo di giorni da/a (fuso orario della prenotazione), un avvocato (user_id), uno stato o updated_since. Ogni titolare di chiave vede le prenotazioni di tutti gli avvocati.

Ambito
bookings:read

Parametri di query

from
string <date>

Solo le prenotazioni a partire da questo giorno incluso (YYYY-MM-DD), confrontate letteralmente con la data del fuso della prenotazione.

Esempio: "2026-01-01"
to
string <date>

Solo le prenotazioni fino a questo giorno incluso (YYYY-MM-DD).

Esempio: "2026-12-31"
user_id
integer>= 1

Filtra su un solo avvocato (user_id da colleagues.list). Ometta per tutti gli avvocati dello studio.

status
string

Filtra per stato.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
updated_since
string <date-time>

Solo le prenotazioni modificate a partire da questo momento ISO 8601 (updated_at è naive nel fuso dello studio).

limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/bookings?from=2026-01-01&to=2026-12-31&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 4321,
      "booking_number": "string",
      "status": "pending",
      "source": "flowyer",
      "lawyer": {
        "user_id": 1234,
        "name": "string"
      },
      "date": "2026-10-30",
      "start_time": "string",
      "end_time": "string",
      "start": "2026-10-30T09:15:00+01:00",
      "end": "2026-10-30T09:15:00+01:00",
      "timezone": "string",
      "location_preference": "office",
      "meeting_link": "string",
      "client": {
        "name": "string",
        "email": "info@example.hu",
        "phone": "string",
        "description": "string"
      },
      "gdpr_consent": true,
      "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
      "cancel_reason": "string",
      "payment": {
        "status": "none",
        "method": "card",
        "amount": 0,
        "currency": "string",
        "invoice_number": "string"
      },
      "confirmed_at": "2026-10-30T09:15:00+01:00",
      "cancelled_at": "2026-10-30T09:15:00+01:00",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni la prenotazione

GET /api/agent/bookings/{id}

Restituisce una prenotazione di appuntamento con l'avvocato, i dettagli del cliente, gli istanti di inizio/fine, lo stato di pagamento e il token di blocco updated_at per bookings.update / .confirm / .cancel. Risponde 404 quando la prenotazione non esiste in questo studio.

Ambito
bookings:read

Parametri di percorso

idobbligatorio
integer>= 1

Id della prenotazione.

Esempio: 4321

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/bookings/4321' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "booking_number": "string",
    "status": "pending",
    "source": "flowyer",
    "lawyer": {
      "user_id": 1234,
      "name": "string"
    },
    "date": "2026-10-30",
    "start_time": "string",
    "end_time": "string",
    "start": "2026-10-30T09:15:00+01:00",
    "end": "2026-10-30T09:15:00+01:00",
    "timezone": "string",
    "location_preference": "office",
    "meeting_link": "string",
    "client": {
      "name": "string",
      "email": "info@example.hu",
      "phone": "string",
      "description": "string"
    },
    "gdpr_consent": true,
    "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
    "cancel_reason": "string",
    "payment": {
      "status": "none",
      "method": "card",
      "amount": 0,
      "currency": "string",
      "invoice_number": "string"
    },
    "confirmed_at": "2026-10-30T09:15:00+01:00",
    "cancelled_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Crea una prenotazione

POST /api/agent/bookings

Fissa un appuntamento e INVIA UN'EMAIL AL CLIENTE con la conferma. Richiede uno slot libero per l'avvocato (altrimenti 409); il calendario dello studio non blocca mai. source è "manual". Un replay con Idempotency-Key non prenota di nuovo né invia di nuovo l'email.

Ambito
bookings:create

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

user_idobbligatorio
integer>= 1

Avvocato con cui è fissato l'appuntamento (user_id da colleagues.list; deve essere un collega attivo dello studio).

Esempio: 42
dateobbligatorio
string <date>

Giorno dell'appuntamento (YYYY-MM-DD) nel fuso orario della prenotazione.

Esempio: "2026-03-02"
timeobbligatorio
string

Ora di inizio HH:MM (24h) nel fuso orario della prenotazione. L'ora di fine è time + la durata dello slot dello studio. Deve essere uno slot libero.

Modello: ^([01]\d|2[0-3]):[0-5]\d$
Esempio: "09:00"
client_nameobbligatorio
stringal massimo 255 caratteri

Il nome del cliente. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$
Esempio: "Kovács Anna"
client_emailobbligatorio
stringal massimo 255 caratteri

L'e-mail del cliente: il destinatario della conferma.

Esempio: "anna@example.com"
client_phone
string | nullal massimo 50 caratteri

Il telefono del cliente. Testo semplice.

Modello: ^[^<>]*$
client_description
string | nullal massimo 2000 caratteri

Oggetto / note dal cliente. Testo semplice.

Modello: ^[^<>]*$
location_preference
string

Consulenza in studio o online. Predefinito "office".

Valori ammessi: "office" "online"
Predefinito: "office"
meeting_link
string | nullal massimo 500 caratteri

URL della riunione online (http/https), per una consulenza online.

gdpr_consent
boolean

Registra il consenso del cliente al trattamento dei dati. Predefinito true (il personale dello studio prenota per conto del cliente).

Predefinito: true
auto_confirm
boolean

Quando è true (o lo studio ha la conferma automatica attiva), crea la prenotazione già confermata: esegue la sincronizzazione del calendario e invia al cliente una conferma invece di una richiesta. Altrimenti è pending.

Predefinito: false
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/bookings' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "user_id": 42,
  "date": "2026-03-02",
  "time": "09:00",
  "client_name": "Kovács Anna",
  "client_email": "anna@example.com"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "booking_number": "string",
    "status": "pending",
    "source": "flowyer",
    "lawyer": {
      "user_id": 1234,
      "name": "string"
    },
    "date": "2026-10-30",
    "start_time": "string",
    "end_time": "string",
    "start": "2026-10-30T09:15:00+01:00",
    "end": "2026-10-30T09:15:00+01:00",
    "timezone": "string",
    "location_preference": "office",
    "meeting_link": "string",
    "client": {
      "name": "string",
      "email": "info@example.hu",
      "phone": "string",
      "description": "string"
    },
    "gdpr_consent": true,
    "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
    "cancel_reason": "string",
    "payment": {
      "status": "none",
      "method": "card",
      "amount": 0,
      "currency": "string",
      "invoice_number": "string"
    },
    "confirmed_at": "2026-10-30T09:15:00+01:00",
    "cancelled_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Aggiorna la prenotazione

PATCH /api/agent/bookings/{id}

Riprogramma (data + ora insieme, con nuova verifica di uno slot libero) o modifica una prenotazione (telefono, note, link della riunione, luogo). Scrive solo i campi che invia. Notifica all'avvocato una riprogrammazione, mai al cliente. Passi expected_updated_at dalla sua ultima lettura; una scrittura obsoleta risponde 409.

Ambito
bookings:update

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

date
string <date>

Nuovo giorno (YYYY-MM-DD) nel fuso orario della prenotazione. Invii data E ora insieme per riprogrammare.

Esempio: "2026-03-05"
time
string

Nuova ora di inizio HH:MM. L'ora di fine viene ricalcolata dalla durata dello slot dello studio. Invii data E ora insieme.

Modello: ^([01]\d|2[0-3]):[0-5]\d$
Esempio: "11:00"
client_phone
string | nullal massimo 50 caratteri

Il telefono del cliente. Testo semplice. "" lo cancella.

Modello: ^[^<>]*$
client_description
string | nullal massimo 2000 caratteri

Oggetto / note. Testo semplice. "" lo cancella.

Modello: ^[^<>]*$
meeting_link
string | nullal massimo 500 caratteri

URL della riunione online (http/https). "" lo cancella.

location_preference
string

Consulenza in studio o online.

Valori ammessi: "office" "online"

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/bookings/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "date": "2026-03-05",
  "time": "11:00"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "booking_number": "string",
    "status": "pending",
    "source": "flowyer",
    "lawyer": {
      "user_id": 1234,
      "name": "string"
    },
    "date": "2026-10-30",
    "start_time": "string",
    "end_time": "string",
    "start": "2026-10-30T09:15:00+01:00",
    "end": "2026-10-30T09:15:00+01:00",
    "timezone": "string",
    "location_preference": "office",
    "meeting_link": "string",
    "client": {
      "name": "string",
      "email": "info@example.hu",
      "phone": "string",
      "description": "string"
    },
    "gdpr_consent": true,
    "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
    "cancel_reason": "string",
    "payment": {
      "status": "none",
      "method": "card",
      "amount": 0,
      "currency": "string",
      "invoice_number": "string"
    },
    "confirmed_at": "2026-10-30T09:15:00+01:00",
    "cancelled_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Conferma la prenotazione

POST /api/agent/bookings/{id}/confirm

Conferma una prenotazione pending e INVIA UN'EMAIL AL CLIENTE con la conferma (con il link della riunione per una online). Solo una prenotazione pending può essere confermata; qualsiasi altro stato risponde 409, quindi un nuovo tentativo non invia mai di nuovo l'email. Facoltativamente passi expected_updated_at come token di blocco.

Ambito
bookings:send

Parametri di percorso

idobbligatorio
integer>= 1

Id della prenotazione.

Esempio: 4321

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Token opzionale di blocco ottimistico: l'updated_at dalla sua ultima lettura. Se la prenotazione è cambiata da allora, l'API risponde 409 e Lei rilegge prima di riprovare.

meeting_link
string | nullal massimo 500 caratteri

URL della riunione online (http/https) da impostare sulla prenotazione prima che l'e-mail di conferma venga inviata.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/bookings/4321/confirm' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "booking_number": "string",
    "status": "pending",
    "source": "flowyer",
    "lawyer": {
      "user_id": 1234,
      "name": "string"
    },
    "date": "2026-10-30",
    "start_time": "string",
    "end_time": "string",
    "start": "2026-10-30T09:15:00+01:00",
    "end": "2026-10-30T09:15:00+01:00",
    "timezone": "string",
    "location_preference": "office",
    "meeting_link": "string",
    "client": {
      "name": "string",
      "email": "info@example.hu",
      "phone": "string",
      "description": "string"
    },
    "gdpr_consent": true,
    "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
    "cancel_reason": "string",
    "payment": {
      "status": "none",
      "method": "card",
      "amount": 0,
      "currency": "string",
      "invoice_number": "string"
    },
    "confirmed_at": "2026-10-30T09:15:00+01:00",
    "cancelled_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Annulla la prenotazione

POST /api/agent/bookings/{id}/cancel

Annulla una prenotazione e INVIA UN'EMAIL AL CLIENTE (e all'avvocato) con l'annullamento. Una prenotazione già annullata o completata risponde 409, quindi un nuovo tentativo non invia mai di nuovo l'email. Una prenotazione pagata viene annullata ma mai rimborsata (se ne occupa lo studio). Facoltativamente passi expected_updated_at.

Ambito
bookings:send

Parametri di percorso

idobbligatorio
integer>= 1

Id della prenotazione.

Esempio: 4321

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Token opzionale di blocco ottimistico: l'updated_at dalla sua ultima lettura. Se la prenotazione è cambiata da allora, l'API risponde 409.

reason
string | nullal massimo 255 caratteri

Motivo registrato come cancel_reason e mostrato nell'e-mail di annullamento. Testo semplice; "<" e ">" non sono consentiti.

Modello: ^[^<>]*$

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer
Esempio: 4321
booking_number
string

Numero di prenotazione leggibile, ad es. "#B-0001".

status
string

pending = in attesa della conferma dell'avvocato; confirmed = approvata; cancelled/completed; awaiting_payment/expired appartengono al flusso paga-prima-della-conferma.

Valori ammessi: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

Da dove proviene la prenotazione. Una prenotazione creata tramite API è "manual".

Valori ammessi: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

L'avvocato (user_id da colleagues.list) con cui è fissato l'appuntamento.

Campi di lawyer
user_id
integer
name
string | null
date
string <date> | null

Data di calendario nel fuso orario della prenotazione (YYYY-MM-DD), memorizzata letteralmente.

start_time
string | null

Ora di inizio HH:MM nel fuso orario della prenotazione.

end_time
string | null

Ora di fine HH:MM nel fuso orario della prenotazione.

start
string <date-time> | null

Istante ISO 8601 non ambiguo dell'inizio, composto con il fuso orario della prenotazione. Lo usi per confrontare istanti tra fusi diversi.

end
string <date-time> | null

Istante ISO 8601 non ambiguo della fine.

timezone
string

Il fuso orario della prenotazione (booking_settings.timezone), ad es. "Europe/Budapest". Governa date, start_time e end_time.

location_preference
string

Se la consulenza è in studio o online.

Valori ammessi: "office" "online"
meeting_link
string | null

URL della riunione online, quando impostato.

client
object

Il cliente esterno che ha prenotato: nome, e-mail, telefono e l'oggetto/note. Dati personali, solo per il personale dello studio.

Campi di client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Se è registrato il consenso del cliente al trattamento dei dati.

gdpr_consent_at
string <date-time> | null

Quando è stato registrato il consenso.

cancel_reason
string | null

Motivo registrato all'annullamento.

payment
object

Stato di pagamento di sola lettura. L'API non modifica mai il pagamento; le commissioni di prenotazione sono gestite in Flowyer.

Campi di payment
status
string
Valori ammessi: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori ammessi: "card" "transfer"
amount
number | null
currency
string | null
invoice_number
string | null
confirmed_at
string <date-time> | null
cancelled_at
string <date-time> | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a bookings.update / bookings.confirm / bookings.cancel come expected_updated_at.

created_via_api
object | null

Presente quando un agente esterno ha creato la prenotazione tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/bookings/4321/cancel' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "booking_number": "string",
    "status": "pending",
    "source": "flowyer",
    "lawyer": {
      "user_id": 1234,
      "name": "string"
    },
    "date": "2026-10-30",
    "start_time": "string",
    "end_time": "string",
    "start": "2026-10-30T09:15:00+01:00",
    "end": "2026-10-30T09:15:00+01:00",
    "timezone": "string",
    "location_preference": "office",
    "meeting_link": "string",
    "client": {
      "name": "string",
      "email": "info@example.hu",
      "phone": "string",
      "description": "string"
    },
    "gdpr_consent": true,
    "gdpr_consent_at": "2026-10-30T09:15:00+01:00",
    "cancel_reason": "string",
    "payment": {
      "status": "none",
      "method": "card",
      "amount": 0,
      "currency": "string",
      "invoice_number": "string"
    },
    "confirmed_at": "2026-10-30T09:15:00+01:00",
    "cancelled_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  }
}

Ticket di assistenza

Elenca i ticket

GET /api/agent/tickets

Elenca i ticket di assistenza che l'utente può vedere (visibilità per casella di posta), prima l'attività più recente. Filtra per stato (predefinito open_states = new+open+pending; "all" include closed), casella di posta, assegnatario, email del richiedente, o testo libero su oggetto/richiedente/numero di ticket.

Ambito
tickets:read
Permesso Flowyer
ticketing:read

Parametri di query

status
string

open_states (predefinito) = new+open+pending (la vista predefinita del web); "all" include closed; oppure uno stato esatto.

Valori ammessi: "new" "open" "pending" "closed" "open_states" "all"
Predefinito: "open_states"
mailbox_id
integer>= 1

Solo i ticket di questa casella di posta. Una casella di posta che l'utente non può vedere produce un elenco vuoto (mai una fuga di dati).

Esempio: 7
assigned_to_user_id
integer>= 0

Solo i ticket assegnati a questo collega (id da colleagues.list); 0 = solo i ticket non assegnati. Ometta per qualsiasi assegnatario.

requester_email
stringal massimo 255 caratteri

Solo i ticket la cui email del richiedente esterno corrisponde esattamente (ignorando maiuscole/minuscole).

Esempio: "ugyfel@example.com"
q
stringal massimo 100 caratteri

Ricerca a testo libero su oggetto, nome/email del richiedente e numero di ticket (maiuscole/minuscole ignorate).

Esempio: "számla"
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id del ticket (da usare con tickets.get / tickets.update).

Esempio: 4321
ticket_number
string | null

Numero di ticket leggibile, ad es. FLW-000123.

subject
string | null
status
string
Valori ammessi: "new" "open" "pending" "closed"
priority
string
Valori ammessi: "low" "normal" "high"
mailbox
object | null

La casella di posta attraverso cui è arrivato il ticket (registro centrale).

Campi di mailbox
id
integer
email
string | null
display_name
string | null
requester
object

La persona esterna che ha scritto.

Campi di requester
email
string | null
name
string | null
assigned_to
object | null

Il collega a cui è assegnato il ticket, oppure null quando non assegnato.

Campi di assigned_to
user_id
integer
name
string | null
matter
object | null

La pratica collegata al ticket, oppure null.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente collegato al ticket, oppure null.

Campi di client
id
integer
name
string
last_message_at
string <date-time> | null

Ora dell'attività più recente del thread; l'elenco è ordinato in base ad essa, prima i più recenti.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a tickets.update come expected_updated_at.

created_via_api
object | null

Presente quando il ticket è stato creato tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/tickets?mailbox_id=7&requester_email=ugyfel%40example.com&q=sz%C3%A1mla' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 4321,
      "ticket_number": "string",
      "subject": "string",
      "status": "new",
      "priority": "low",
      "mailbox": {
        "id": 1234,
        "email": "info@example.hu",
        "display_name": "string"
      },
      "requester": {
        "email": "info@example.hu",
        "name": "string"
      },
      "assigned_to": {
        "user_id": 1234,
        "name": "string"
      },
      "matter": {
        "id": 1234,
        "case_number": "string"
      },
      "client": {
        "id": 1234,
        "name": "string"
      },
      "last_message_at": "2026-10-30T09:15:00+01:00",
      "created_at": "2026-10-30T09:15:00+01:00",
      "updated_at": "2026-10-30T09:15:00+01:00",
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Ottieni il ticket

GET /api/agent/tickets/{id}

Restituisce un ticket di assistenza con il suo thread di messaggi (prima i più vecchi) e la pratica/il cliente collegati. Risponde 404 quando il ticket non esiste o si trova in una casella di posta che l'utente non può vedere. La lettura non modifica mai il ticket (un ticket NEW non viene portato a OPEN).

Ambito
tickets:read
Permesso Flowyer
ticketing:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del ticket.

Esempio: 4321

Parametri di query

messages_limit
integer | null>= 1<= 500

Restituisce solo gli N messaggi più recenti del thread (comunque presentati prima i più vecchi). Ometta per l'intero thread.

Risposte

200

OK.

dataobbligatorio
object
Campi di data
id
integer

Id del ticket (da usare con tickets.get / tickets.update).

Esempio: 4321
ticket_number
string | null

Numero di ticket leggibile, ad es. FLW-000123.

subject
string | null
status
string
Valori ammessi: "new" "open" "pending" "closed"
priority
string
Valori ammessi: "low" "normal" "high"
mailbox
object | null

La casella di posta attraverso cui è arrivato il ticket (registro centrale).

Campi di mailbox
id
integer
email
string | null
display_name
string | null
requester
object

La persona esterna che ha scritto.

Campi di requester
email
string | null
name
string | null
assigned_to
object | null

Il collega a cui è assegnato il ticket, oppure null quando non assegnato.

Campi di assigned_to
user_id
integer
name
string | null
matter
object | null

La pratica collegata al ticket, oppure null.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente collegato al ticket, oppure null.

Campi di client
id
integer
name
string
last_message_at
string <date-time> | null

Ora dell'attività più recente del thread; l'elenco è ordinato in base ad essa, prima i più recenti.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a tickets.update come expected_updated_at.

created_via_api
object | null

Presente quando il ticket è stato creato tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
messages
object[]

Il thread di messaggi, prima i più vecchi.

Campi di messages
id
integer
direction
string

in = dal richiedente, out = risposta/conferma automatica inviata dalla casella di posta, note = interno.

Valori ammessi: "in" "out" "note"
from
object
Campi di from
email
string | null
name
string | null
to
object[]
Campi di to
email
string
name
string | null
cc
object[]
Campi di cc
email
string
name
string | null
sent_status
string | null

Stato di consegna di un messaggio in uscita; null per in/note.

Valori ammessi: "pending" "sent" "failed" "scheduled"
body_html
string | null

Corpo del messaggio come HTML sanificato (già sicuro al momento della memorizzazione).

body_text
string | null
has_attachments
boolean
author
object | null

Il collega che ha scritto un messaggio out/note; null per un messaggio in entrata.

Campi di author
user_id
integer
name
string | null
created_at
string <date-time> | null
linked_matter
object | null

La pratica collegata al ticket (come matter).

Campi di linked_matter
id
integer
case_number
string
linked_client
object | null

Il cliente collegato al ticket (come client).

Campi di linked_client
id
integer
name
string
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/tickets/4321' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "ticket_number": "string",
    "subject": "string",
    "status": "new",
    "priority": "low",
    "mailbox": {
      "id": 1234,
      "email": "info@example.hu",
      "display_name": "string"
    },
    "requester": {
      "email": "info@example.hu",
      "name": "string"
    },
    "assigned_to": {
      "user_id": 1234,
      "name": "string"
    },
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "last_message_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    },
    "messages": [
      {
        "id": 1234,
        "direction": "in",
        "from": {
          "email": "info@example.hu",
          "name": "string"
        },
        "to": [
          {
            "email": "info@example.hu",
            "name": "string"
          }
        ],
        "cc": [
          {
            "email": "info@example.hu",
            "name": "string"
          }
        ],
        "sent_status": "pending",
        "body_html": "string",
        "body_text": "string",
        "has_attachments": true,
        "author": {
          "user_id": 1234,
          "name": "string"
        },
        "created_at": "2026-10-30T09:15:00+01:00"
      }
    ],
    "linked_matter": {
      "id": 1234,
      "case_number": "string"
    },
    "linked_client": {
      "id": 1234,
      "name": "string"
    }
  }
}

Rispondi al ticket

POST /api/agent/tickets/{id}/reply

Risponde a un ticket di assistenza e INVIA la risposta via email al richiedente esterno (attraverso la casella di posta del ticket). Il corpo è HTML formattato, sanificato lato server prima della memorizzazione. Un nuovo tentativo con lo stesso Idempotency-Key non invia mai una seconda email.

Ambito
tickets:reply
Permesso Flowyer
ticketing:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del ticket (deve essere visibile tramite l'ACL della casella di posta).

Esempio: 4321

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

body_htmlobbligatorio
stringalmeno 1 caratteri

La risposta, HTML formattato (come lo produce TinyMCE). Ripulito lato server con HTMLPurifier prima della memorizzazione e prima dell'invio. Al massimo 100000 caratteri; rifiutato se la sanificazione non lascia nulla.

Esempio: "<p>Köszönjük megkeresését, csatoltan küldjük a választ.</p>"
cc
string[]al massimo 10 elementi

Destinatari aggiuntivi in Cc (al massimo 10). Il richiedente e la casella di posta sono esclusi automaticamente; un indirizzo non valido risponde 422.

status
string

Stato del ticket da impostare dopo aver risposto (predefinito "pending" = in attesa del richiedente). Registra un evento di cambio stato.

Valori ammessi: "new" "open" "pending" "closed"
Predefinito: "pending"
append_signature
boolean

Aggiunge la firma del ticket salvata dall'utente della chiave solo alla posta in USCITA (mai memorizzata nel thread).

Predefinito: false
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
ticket_id
integer
Esempio: 4321
message_id
integer

Id della riga ticket_messages in uscita creata.

Esempio: 98765
direction
string

Sempre "out".

sent_status
string | null

"pending" al momento della creazione; l'invio asincrono lo porta in seguito a sent/failed.

Valori ammessi: "pending" "sent" "failed" "scheduled"
status
string

Lo stato del ticket dopo la risposta.

Valori ammessi: "new" "open" "pending" "closed"
created_at
string <date-time> | null
created_via_api
object | null

Presente quando la risposta è stata creata tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
ticket_id
integer
Esempio: 4321
message_id
integer

Id della riga ticket_messages in uscita creata.

Esempio: 98765
direction
string

Sempre "out".

sent_status
string | null

"pending" al momento della creazione; l'invio asincrono lo porta in seguito a sent/failed.

Valori ammessi: "pending" "sent" "failed" "scheduled"
status
string

Lo stato del ticket dopo la risposta.

Valori ammessi: "new" "open" "pending" "closed"
created_at
string <date-time> | null
created_via_api
object | null

Presente quando la risposta è stata creata tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/tickets/4321/reply' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "body_html": "<p>Köszönjük megkeresését, csatoltan küldjük a választ.</p>"
}'

Esempi di risposta

{
  "data": {
    "ticket_id": 4321,
    "message_id": 98765,
    "direction": "string",
    "sent_status": "pending",
    "status": "new",
    "created_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "created": true
}

Cambia lo stato del ticket

PATCH /api/agent/tickets/{id}

Cambia lo stato di un ticket (new, open, pending o closed). "closed" imposta closed_at; qualsiasi altro stato lo cancella. Passi expected_updated_at dalla sua ultima lettura; una modifica in conflitto risponde 409. Risponde 404 quando il ticket non è visibile.

Ambito
tickets:update
Permesso Flowyer
ticketing:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del record da modificare.

Corpo della richiesta application/json

expected_updated_at
string <date-time> | null

Il valore updated_at dalla sua lettura più recente di questo record (obbligatorio ogni volta che il record ne ha uno). Se il record è cambiato da allora (un collega lo ha modificato), l'API risponde 409 e deve rileggere prima di riprovare. Un record legacy il cui updated_at è null accetta null.

statusobbligatorio
string

Il nuovo stato. "closed" imposta closed_at; qualsiasi altro stato lo cancella.

Valori ammessi: "new" "open" "pending" "closed"
Esempio: "open"

Risposte

200

Aggiornato.

dataobbligatorio
object
Campi di data
id
integer

Id del ticket (da usare con tickets.get / tickets.update).

Esempio: 4321
ticket_number
string | null

Numero di ticket leggibile, ad es. FLW-000123.

subject
string | null
status
string
Valori ammessi: "new" "open" "pending" "closed"
priority
string
Valori ammessi: "low" "normal" "high"
mailbox
object | null

La casella di posta attraverso cui è arrivato il ticket (registro centrale).

Campi di mailbox
id
integer
email
string | null
display_name
string | null
requester
object

La persona esterna che ha scritto.

Campi di requester
email
string | null
name
string | null
assigned_to
object | null

Il collega a cui è assegnato il ticket, oppure null quando non assegnato.

Campi di assigned_to
user_id
integer
name
string | null
matter
object | null

La pratica collegata al ticket, oppure null.

Campi di matter
id
integer
case_number
string
client
object | null

Il cliente collegato al ticket, oppure null.

Campi di client
id
integer
name
string
last_message_at
string <date-time> | null

Ora dell'attività più recente del thread; l'elenco è ordinato in base ad essa, prima i più recenti.

created_at
string <date-time> | null
updated_at
string <date-time> | null

Passi questo a tickets.update come expected_updated_at.

created_via_api
object | null

Presente quando il ticket è stato creato tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
updated
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

Il record è cambiato da quando lo ha letto (record_conflict: expected_updated_at non corrisponde più; lo rilegga e riprovi con il nuovo updated_at).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X PATCH 'https://www.flowyer.it/api/agent/tickets/1234' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -d '{
  "expected_updated_at": "2026-10-30T09:15:00+01:00",
  "status": "open"
}'

Esempi di risposta

{
  "data": {
    "id": 4321,
    "ticket_number": "string",
    "subject": "string",
    "status": "new",
    "priority": "low",
    "mailbox": {
      "id": 1234,
      "email": "info@example.hu",
      "display_name": "string"
    },
    "requester": {
      "email": "info@example.hu",
      "name": "string"
    },
    "assigned_to": {
      "user_id": 1234,
      "name": "string"
    },
    "matter": {
      "id": 1234,
      "case_number": "string"
    },
    "client": {
      "id": 1234,
      "name": "string"
    },
    "last_message_at": "2026-10-30T09:15:00+01:00",
    "created_at": "2026-10-30T09:15:00+01:00",
    "updated_at": "2026-10-30T09:15:00+01:00",
    "created_via_api": {
      "kind": "key",
      "key_id": 1234,
      "key_name": "string",
      "user_id": 1234,
      "user": "string",
      "at": "2026-10-30T09:15:00+01:00"
    }
  },
  "updated": true
}

Portale clienti

Elenca i portali clienti

GET /api/agent/portals

Elenca i portali clienti (thread) a cui l'utente può accedere: la pratica, i partecipanti lato cliente, i conteggi dei messaggi e dei partecipanti e l'ora dell'ultimo messaggio, prima i più recenti. Facoltativamente filtrati su una sola pratica (matter_id). Una pratica ha al massimo un portale.

Ambito
portal:read
Permesso Flowyer
client-portal:read, cases:read

Parametri di query

matter_id
integer>= 1

Solo il portale di questa pratica (404 matter_not_visible quando la pratica non è visibile). Una pratica ha al massimo un portale.

Esempio: 1234
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

Id del portale (thread) - l'identificatore per portal.messages.list e portal.reply.

Esempio: 57
matter
object

La pratica (causa) a cui appartiene il portale.

Campi di matter
id
integer
case_number
string
client_participants
object[]

I partecipanti esterni lato cliente con cui lo studio sta comunicando.

Campi di client_participants
name
string | null
kind
string

client = un mandante, contact = un contatto del cliente, email = una concessione legacy solo e-mail.

Valori ammessi: "client" "contact" "email"
participant_count
integer

Numero di partecipanti attivi (personale e cliente).

message_count
integer

Numero di messaggi non eliminati nel thread.

last_message_at
string <date-time> | null

Quando è stato pubblicato il messaggio non eliminato più recente, ISO 8601 nel fuso dello studio; null per un thread vuoto.

unread_for_me
integer | null

Messaggi non letti per la riga partecipante dell'utente che agisce; null quando l'utente che agisce non è un partecipante di questo portale.

created_at
string <date-time> | null
paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/portals?matter_id=1234&limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 57,
      "matter": {
        "id": 1234,
        "case_number": "string"
      },
      "client_participants": [
        {
          "name": "string",
          "kind": "client"
        }
      ],
      "participant_count": 0,
      "message_count": 0,
      "last_message_at": "2026-10-30T09:15:00+01:00",
      "unread_for_me": 0,
      "created_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Elenca i messaggi del portale

GET /api/agent/portals/{id}/messages

Elenca i messaggi di un thread del portale clienti, prima i più vecchi, con l'autore (personale o cliente), il corpo in testo semplice ed eventuali metadati degli allegati. Risponde 404 quando il portale non esiste o non è accessibile. Non contrassegna i messaggi come letti.

Ambito
portal:read
Permesso Flowyer
client-portal:read, cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del portale (deve essere accessibile).

Esempio: 57

Parametri di query

include_deleted
boolean

Includi i messaggi eliminati (il loro corpo è vuoto). Predefinito false.

Predefinito: false
limit
integer>= 1<= 100

Dimensione della pagina, 1-100. Valore predefinito 25.

Predefinito: 25
Esempio: 25
offset
integer>= 0

Numero di record da saltare. Usi offset + limit della pagina precedente per ottenere quella successiva; pagination.total è il conteggio totale.

Predefinito: 0
Esempio: 0

Risposte

200

OK.

dataobbligatorio
object[]
Campi di data
id
integer

portal_messages.id.

Esempio: 8012
author
object

Chi ha scritto il messaggio.

Campi di author
participant_id
integer | null
name
string | null
kind
string

staff = un collega dello studio, client = il cliente esterno.

Valori ammessi: "staff" "client"
direction
string

from_firm = un autore del personale, from_client = il cliente esterno.

Valori ammessi: "from_firm" "from_client"
body
string

Il messaggio in testo semplice (<br> decodificato in interruzioni di riga). Stringa vuota per un messaggio eliminato.

attachment
object | null

Metadati dell'allegato quando il messaggio ha un documento; il suo download è fuori ambito. Null quando non ce n'è nessuno.

Campi di attachment
portal_document_id
integer
file_name
string
is_deleted
boolean
deleted_at
string <date-time> | null
created_at
string <date-time> | null

Quando il messaggio è stato pubblicato, ISO 8601 nel fuso dello studio.

paginationobbligatorio
object
Campi di pagination
limitobbligatorio
integer
offsetobbligatorio
integer
totalobbligatorio
integer

Numero totale di record corrispondenti.

400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl 'https://www.flowyer.it/api/agent/portals/57/messages?limit=25' \
  -H 'Authorization: Bearer flw_...'

Esempi di risposta

{
  "data": [
    {
      "id": 8012,
      "author": {
        "participant_id": 1234,
        "name": "string",
        "kind": "staff"
      },
      "direction": "from_firm",
      "body": "string",
      "attachment": {
        "portal_document_id": 1234,
        "file_name": "string"
      },
      "is_deleted": true,
      "deleted_at": "2026-10-30T09:15:00+01:00",
      "created_at": "2026-10-30T09:15:00+01:00"
    }
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 1
  }
}

Rispondi nel portale clienti

POST /api/agent/portals/{id}/messages

Pubblica una risposta del personale in un thread del portale clienti. Il cliente la vede nel portale e viene notificato via e-mail (un avviso con magic-link firmato, non il testo); i colleghi ricevono una notifica in-app. Testo semplice, sottoposto a escape alla memorizzazione. 404 quando il portale non è accessibile.

Ambito
portal:reply
Permesso Flowyer
client-portal:read, cases:read

Parametri di percorso

idobbligatorio
integer>= 1

Id del portale in cui rispondere (deve essere accessibile).

Esempio: 57

Parametri di intestazione

Idempotency-Key
stringal massimo 128 caratteri

Consigliato a ogni creazione. Un valore univoco per operazione logica (ad es. un UUID). Lo stesso valore restituisce lo stesso record: riprovare con esso restituisce il record creato la prima volta invece di crearne un secondo. Valori diversi creano sempre record diversi. I client che non possono inviare header possono passare lo stesso valore nel campo del corpo idempotency_key. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$

Corpo della richiesta application/json

bodyobbligatorio
stringalmeno 1 caratterial massimo 20000 caratteri

La risposta, testo semplice. Le parentesi angolari sono accettate e sottoposte a escape alla memorizzazione. Al massimo 20000 caratteri.

Esempio: "Tisztelt Ügyfelünk! A beadványt ma benyújtottuk."
idempotency_key
stringal massimo 128 caratteri

Stesso ruolo dell'header Idempotency-Key, per i client che non possono inviare header personalizzati. Lettere, cifre, _, -, : o ., al massimo 128 caratteri.

Modello: ^[A-Za-z0-9_\-:.]{1,128}$
Esempio: "b8f1c2e0-6f7a-4d2e-9c1b-2a3d4e5f6a7b"

Risposte

201

Creato.

dataobbligatorio
object
Campi di data
message
object

La risposta pubblicata.

Campi di message
id
integer
Esempio: 8012
author
object

L'utente del personale che ha pubblicato la risposta.

Campi di author
participant_id
integer | null
name
string | null
kind
string

staff = un collega dello studio, client = il cliente esterno.

Valori ammessi: "staff" "client"
direction
string

Sempre "from_firm" per una risposta pubblicata tramite questa API.

Valori ammessi: "from_firm" "from_client"
body
string

Il messaggio pubblicato in testo semplice.

created_at
string <date-time> | null
portal
object

Il portale (thread) e la sua pratica in cui è stata pubblicata la risposta.

Campi di portal
id
integer
matter
object
Campi di matter
id
integer
case_number
string
created_via_api
object | null

Provenienza del messaggio creato tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: true
200

Replay idempotente: questo Idempotency-Key (o, senza chiave, una richiesta identica entro 120 secondi) ha già creato il record; viene restituito di nuovo, nulla di nuovo è stato creato.

dataobbligatorio
object
Campi di data
message
object

La risposta pubblicata.

Campi di message
id
integer
Esempio: 8012
author
object

L'utente del personale che ha pubblicato la risposta.

Campi di author
participant_id
integer | null
name
string | null
kind
string

staff = un collega dello studio, client = il cliente esterno.

Valori ammessi: "staff" "client"
direction
string

Sempre "from_firm" per una risposta pubblicata tramite questa API.

Valori ammessi: "from_firm" "from_client"
body
string

Il messaggio pubblicato in testo semplice.

created_at
string <date-time> | null
portal
object

Il portale (thread) e la sua pratica in cui è stata pubblicata la risposta.

Campi di portal
id
integer
matter
object
Campi di matter
id
integer
case_number
string
created_via_api
object | null

Provenienza del messaggio creato tramite questa API.

Campi di created_via_api
kind
string

"key": creato con una chiave API statica; "oauth": creato da un'app connessa tramite OAuth.

Valori ammessi: "key" "oauth"
key_id
integer

Id della chiave API (tipo "key") o dell'app connessa (tipo "oauth"); i due sono numerati separatamente.

key_name
string

Nome che l'utente ha assegnato alla chiave API, ad es. "Grok integration", oppure il nome dell'app connessa per il tipo "oauth", ad es. "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
created
boolean
Valore: false
idempotent_replay
boolean
Valore: true
400

Richiesta malformata: corpo JSON non valido, host errato (usi l'host www.) o richiesta illeggibile.

401

La chiave è mancante, non valida, revocata o scaduta, oppure il suo utente non è più attivo.

403

Scope mancante (scope_missing), permesso di modulo Flowyer mancante (module_forbidden), API disabilitata per lo studio, licenza scaduta o studio archiviato.

404

Endpoint sconosciuto, oppure il record non esiste / non è visibile all'utente. replay_not_visible: questo Idempotency-Key (o, senza chiave, una richiesta identica) ha già creato il record (details.record_id), ma da allora è stato eliminato o non è visibile all'utente; nulla di nuovo è stato creato, non lo ricrei.

405

Metodo non offerto su questo percorso (DELETE e PUT non lo sono mai; PATCH solo dove è offerto un aggiornamento).

409

L'Idempotency-Key è stato usato per un altro tipo di risorsa (idempotency_key_reused), oppure, senza chiave, una richiesta identica è in fase di elaborazione in questo momento (duplicate_in_progress; riprovi a breve).

413

Il corpo della richiesta è troppo grande (request_too_large).

422

Validazione non riuscita o campo sconosciuto; details.fields elenca gli errori dei campi.

429

Limite di frequenza superato; Retry-After indica quando riprovare.

503

Lo studio è temporaneamente non disponibile (manutenzione o configurazione in corso); Retry-After indica quando riprovare.

default

Qualsiasi altro errore, nello stesso envelope.

Esempi di richiesta

curl -X POST 'https://www.flowyer.it/api/agent/portals/57/messages' \
  -H 'Authorization: Bearer flw_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f3a9c21-1b2c-4d5e-8f90-0a1b2c3d4e5f' \
  -d '{
  "body": "Tisztelt Ügyfelünk! A beadványt ma benyújtottuk."
}'

Esempi di risposta

{
  "data": {
    "message": {
      "id": 8012,
      "author": {
        "participant_id": 1234,
        "name": "string",
        "kind": "staff"
      },
      "direction": "from_firm",
      "body": "string",
      "created_at": "2026-10-30T09:15:00+01:00",
      "portal": {
        "id": 1234,
        "matter": {
          "id": 1234,
          "case_number": "string"
        }
      },
      "created_via_api": {
        "kind": "key",
        "key_id": 1234,
        "key_name": "string",
        "user_id": 1234,
        "user": "string",
        "at": "2026-10-30T09:15:00+01:00"
      }
    }
  },
  "created": true
}