Flowyer API

Referința API Flowyer

Versiunea API: 25ac141b2e28

Descrierea completă a REST API Flowyer pentru dezvoltatori: endpointuri, parametri, răspunsuri și exemple de cod.

Cu API-ul Flowyer, propriul dumneavoastră software sau un asistent IA poate citi, crea și modifica înregistrări (dosare, clienți, sarcini, ore de lucru, costuri și documente) în numele unui utilizator Flowyer. Fiecare cerere rulează exact cu permisiunile acelui utilizator, restrânse suplimentar de domeniile cheii sau ale autorizării. Prin API nu se poate șterge nimic.

Descrierile endpointurilor și ale câmpurilor sunt în engleză, deoarece asistenții IA citesc exact acest text.

URL de bază

Toate endpointurile se află la adresele de mai jos. Folosiți întotdeauna exact gazda https care începe cu www., deoarece o redirecționare ar elimina antetul Authorization.

URL de bază

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

Autentificare

Fiecare cerere necesită un token Bearer în antetul Authorization. Există două tipuri de token; endpointurile le tratează la fel.

Cheie API personală

Utilizatorul o creează în Flowyer la Setări > Chei API, după ce un administrator al biroului a activat API-ul. O cheie începe cu flw_, este afișată o singură dată și poate fi revocată oricând, cu efect imediat.

OAuth 2.1 pentru aplicațiile conectate

O integrare destinată altor utilizatori solicită acces prin fluxul OAuth 2.1 Authorization Code + PKCE (S256) în locul unei chei; clienții se pot înregistra dinamic. Un token de acces este valabil 60 minute, un token de reîmprospătare 60 zile, iar perechea este înlocuită la fiecare utilizare. Codul code_verifier PKCE are între 43 și 128 de caractere din A-Z, a-z, 0-9 și - . _ ~ (RFC 7636 4.1), adică base64url fără caractere de umplere: un "=" final este respins.

Metadatele serverului
https://www.flowyer.com/.well-known/oauth-authorization-server
Autorizare
https://www.flowyer.com/authorize
Token
https://www.flowyer.com/api/agent/oauth/token
Înregistrarea clientului
https://www.flowyer.com/api/agent/oauth/register
Revocare
https://www.flowyer.com/api/agent/oauth/revoke

Exemple de cerere

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

Domenii

Fiecare endpoint, cu excepția GET /me, necesită un domeniu (scope). Dacă cheia sau autorizarea nu îl include, răspunsul este 403 scope_missing. GET /me nu necesită niciun domeniu: cu el vedeți ce poate face cheia sau autorizarea.

DomeniuSemnificațieEndpointuri
matters:read Citire dosare GETListați dosarele GETGăsiți un dosar după nume GETObțineți un dosar GETListare responsabili ai dosarului
matters:create Creare dosare POSTCreați un dosar
matters:update Modificare dosare PATCHActualizați un dosar POSTAdăugare responsabil de dosar
clients:read Citire clienți GETListare clienți GETRezolvare client după nume GETObținere client
clients:create Creare clienți POSTCreare client
clients:update Modificare clienți PATCHActualizare client
tasks:read Citire sarcini GETListare sarcini GETObținere sarcină
tasks:create Creare sarcini POSTCreare sarcină
tasks:update Modificare sarcini PATCHActualizare sarcină POSTÎnchidere sarcină
workhours:read Citire ore GETListare intrări de timp GETObținere intrare de timp
workhours:create Înregistrare ore POSTÎnregistrare intrare de timp
workhours:update Modificare ore PATCHActualizare intrare de timp
costs:read Citire costuri GETListare costuri GETObținere cost
costs:create Înregistrare costuri POSTÎnregistrare cost
costs:update Modificare costuri PATCHActualizare cost
invoices:read Citire facturi GETListare facturi GETObținere factură
documents:read Listare documente (doar metadate, fără descărcare) GETListați documentele unui dosar GETListați folderele unui dosar
documents:download Descărcare documente (conținut complet) GETDescărcare document
documents:create Încărcare documente POSTCreare folder de dosar POSTÎncepeți încărcarea unui document POSTFinalizați încărcarea unui document
documents:update Redenumire documente PATCHRedenumire document PATCHRedenumire folder de dosar
colleagues:read Listarea colegilor (doar nume) GETListare colegi
knowledge:read Citirea bazei de cunoștințe GETListare articole din baza de cunoștințe GETObținere articol din baza de cunoștințe GETListare categorii din baza de cunoștințe GETObținere categorie din baza de cunoștințe
knowledge:create Crearea intrărilor în baza de cunoștințe POSTCreare articol în baza de cunoștințe POSTCreare categorie în baza de cunoștințe
knowledge:update Modificarea intrărilor în baza de cunoștințe PATCHActualizare articol din baza de cunoștințe PATCHActualizare categorie din baza de cunoștințe
emails:read Citire e-mailuri dosare GETListare e-mailuri de dosar GETObținere e-mail
litigation:read Listare istoric litigiu GETListare istoric litigiu al dosarului
litigation:create Creare înregistrare istoric litigiu POSTCreare intrare în istoricul litigiului
litigation:update Modificare înregistrare istoric litigiu PATCHActualizare intrare din istoricul litigiului
mail_register:read Citire corespondență GETListare registru de corespondență GETObținere intrare din registrul de corespondență
mail_register:create Creare înregistrări corespondență POSTCreare intrare în registrul de corespondență
mail_register:update Modificare înregistrări corespondență PATCHActualizare intrare din registrul de corespondență
comments:read Citirea comentariilor dosarului GETListare comentarii de dosar
comments:create Adăugarea de comentarii la dosar POSTPostare comentariu de dosar
comments:update Editarea propriilor comentarii PATCHEditare comentariu propriu de dosar
trials:read Citire termene de judecată GETListare termene de judecată ale dosarului GETObținere termen de judecată
trials:create Creare termene de judecată POSTCreare termen de judecată
trials:update Modificare termene de judecată PATCHActualizare termen de judecată
courts:read Listarea instanțelor GETListare instanțe
hr:read Citirea concediilor (doar date) GETListare concedii ale personalului
calendar:read Citirea evenimentelor din calendar GETListare evenimente de calendar GETObținere eveniment de calendar
calendar:create Crearea evenimentelor în calendar POSTCreare eveniment de calendar
calendar:update Modificarea evenimentelor din calendar PATCHActualizare eveniment de calendar
bookings:read Vizualizarea programărilor GETListare programări GETObținere programare
bookings:create Crearea de programări (trimite un e-mail clientului) POSTCreare programare
bookings:update Reprogramarea și editarea programărilor PATCHActualizare programare
bookings:send Confirmarea sau anularea programărilor (trimite un e-mail clientului) POSTConfirmare programare POSTAnulare programare
tickets:read Citirea tichetelor de asistență GETListare tichete de asistență GETObținere tichet de asistență
tickets:reply Răspuns la tichete (trimite un e-mail clientului) POSTRăspuns la tichet
tickets:update Modificarea stării tichetului PATCHSchimbare status tichet
portal:read Portal client: citirea conversațiilor și a mesajelor GETListare portaluri client GETListare mesaje de portal
portal:reply Portal client: răspuns către client (trimite un mesaj și un e-mail de notificare) POSTRăspuns în portalul client

Erori

Fiecare eroare are aceeași formă: un cod (error), un mesaj în engleză (message), mesajul în limba biroului (message_localized) și detalii opționale (details). La 401, 403, 404 și 422 nu are sens să repetați cererea neschimbată, cu două excepții: la 404 upload_not_finished finalizați mai întâi încărcarea la upload_url, apoi apelați din nou complete; la un token de acces OAuth expirat (401 expired_key) reînnoiți mai întâi tokenul.

HTTPerrorSemnificație
400 invalid_json use_www_host bad_request Cerere invalidă: corp JSON invalid, gazdă greșită (folosiți gazda www.) sau o cerere ilizibilă.
401 missing_key invalid_key revoked_key expired_key user_inactive office_not_found Cheia lipsește, este invalidă, revocată sau expirată, titularul ei nu mai este activ, ori biroul cheii nu a fost găsit.
403 scope_missing module_forbidden forbidden office_api_disabled licence_expired office_archived Lipsește o permisiune pe cheie sau pe utilizator, ori biroul nu a activat API-ul.
404 not_found matter_not_visible unknown_endpoint upload_not_finished replay_not_visible Înregistrarea nu există sau utilizatorul nu o poate vedea; endpoint necunoscut; fișierul încărcat nu a ajuns încă în stocare (upload_not_finished: încărcați-l la upload_url, apoi apelați din nou complete); ori o creare repetată a cărei înregistrare a fost creată anterior, dar între timp a fost ștearsă sau ascunsă (replay_not_visible: nu s-a creat nimic nou, nu o creați din nou).
405 delete_not_allowed update_not_allowed method_not_allowed Ștergerea nu este posibilă prin API; modificarea doar acolo unde descrierea oferă o operație PATCH.
409 client_exists client_exists_generic idempotency_key_reused duplicate_in_progress record_conflict record_locked duplicate_name Există deja un client cu acel nume; în folder există deja un document cu acel nume (duplicate_name); înregistrarea s-a modificat de când ați citit-o (record_conflict: citiți-o din nou și retrimiteți modificarea cu noul updated_at); înregistrarea a fost facturată sau blocată (record_locked: faceți modificarea în Flowyer); Idempotency-Key a fost folosit pe altă resursă; ori o cerere identică este în curs de procesare.
413 request_too_large file_too_large Corpul cererii este prea mare (request_too_large) sau fișierul de încărcat depășește limita (file_too_large; details.max indică limita în octeți).
422 validation_failed unknown_client unknown_colleague blocked_file_type upload_token_invalid folder_not_in_matter document_name_too_long Un câmp invalid sau lipsă (details.fields arată care); un token de încărcare invalid, deja folosit sau expirat (upload_token_invalid: reluați încărcarea); ori un folder care nu aparține dosarului (folder_not_in_matter).
429 rate_limited auth_rate_limited Prea multe cereri (300 pe minut per cheie); antetul Retry-After spune când să reîncercați.
500 server_error Eroare neașteptată. Cererea a fost înregistrată sub request_id; reîncercați mai târziu și, dacă se repetă, comunicați acest ID asistenței Flowyer.
503 office_maintenance office_setup_incomplete temporarily_unavailable Biroul este temporar indisponibil (întreținere sau configurare în curs); antetul Retry-After spune când să reîncercați.

Exemple de răspuns · 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": "Această cheie API nu are permisiunea \"clients:create\". Permisiunile unei chei existente nu pot fi modificate, așa că titularul cheii trebuie să creeze în Flowyer, la Setări > Chei API, o cheie nouă cu această permisiune și să o folosească în locul celei vechi.",
  "locale": "ro",
  "details": {
    "required_scope": "clients:create"
  },
  "request_id": "3f0c8a5e-2b1d-4c7a-9e6f-5a4b3c2d1e0f"
}

Paginare

Listele de înregistrări se paginează cu parametrii limit și offset (implicit 25, cel mult 100 elemente pe pagină). pagination.total este numărul total de rezultate; offset-ul paginii următoare este offset-ul anterior plus limit. GET /colleagues, GET /clients/resolve și GET /matters/resolve nu se paginează: acceptă doar limit (cu valoare implicită și maximă proprii, vedeți endpointul respectiv) și returnează total și truncated în data, în loc de un obiect pagination, așadar nu le trimiteți offset.

Exemple de răspuns · 200

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

Reîncercări sigure

Fiecare creare acceptă un antet Idempotency-Key (sau un câmp idempotency_key). O cerere repetată cu aceeași valoare returnează înregistrarea creată prima dată (200, idempotent_replay), în loc să creeze alta. Chei diferite creează întotdeauna înregistrări separate. Fără cheie, o creare identică în decurs de 120 secunde returnează prima înregistrare.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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."}'

Modificări și conflicte

O modificare este o cerere PATCH pe calea proprie a înregistrării: se schimbă doar câmpurile trimise, iar un null explicit golește un câmp numai dacă descrierea câmpului permite acest lucru; la unele câmpuri, null păstrează valoarea memorată, așadar citiți descrierea câmpului. Trimiteți în expected_updated_at valoarea updated_at de la ultima citire. Dacă între timp altcineva a modificat înregistrarea, răspunsul este 409 record_conflict; în acest caz citiți din nou înregistrarea.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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 și fus orar

Datele au formatul AAAA-LL-ZZ, momentele urmează ISO 8601 cu decalajul fusului orar al biroului. Fusul orar al biroului se află în câmpul office.timezone al răspunsului GET /me.

Limite

Cel mult 300 cereri pe minut per cheie sau token; peste această limită răspunsul este 429, iar antetul Retry-After spune când să reîncercați. Corpul unei cereri JSON poate avea cel mult 64 KB, un document încărcat cel mult 100 MB.

Versiuni

Versiunea descrierii OpenAPI se schimbă la fiecare modificare și este trimisă și ca antet ETag, astfel încât clienții pot verifica cu If-None-Match dacă s-a schimbat.

Identitate

Cine sunt

GET /api/agent/me

Returnează utilizatorul și biroul pentru care acționează această cheie API, scope-urile cheii (ce poate face) și limitele de rată. Apelați-o prima dată pentru a afla ce operații sunt disponibile; nu necesită niciun scope.

Acest endpoint nu are date de intrare.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
user
object
Câmpurile user
id
integer
name
string | null
language
string | null
office
object
Câmpurile office
id
integer
name
string | null
timezone
string

Zona IANA în care API-ul citește și scrie marcajele temporale, de exemplu Europe/Budapest.

currency_id
integer

Moneda biroului (id-ul de monedă Flowyer): costs.create înregistrează în ea atunci când currency_id este omis.

currency
string | null

Codul ISO al monedei biroului, de exemplu HUF, EUR, RON.

key
object
Câmpurile key
id
integer
name
string

Numele pe care utilizatorul l-a dat acestei chei sau aplicația conectată pentru un token OAuth.

kind
string

"key" = o cheie API statică, "oauth" = un token de acces OAuth 2.1.

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

Primele caractere ale unei chei statice, doar pentru identificare; null pentru OAuth.

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

Scope-urile acestei credențiale, de exemplu "matters:read". O operație al cărei scope lipsește răspunde cu 403.

available_scopes
string[]

Toate scope-urile pe care proprietarul cheii le-ar putea activa în Flowyer.

limits
object
Câmpurile limits
requests_per_minute
integer
list_max_limit
integer
channel
string

Cum a ajuns cererea la Flowyer.

Valori permise: "rest" "mcp"
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Parametru de interogare necunoscut (această operație nu acceptă niciunul); details.fields îl numește.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
  }
}

Colegi

Listare colegi

GET /api/agent/colleagues

Listează colegii activi ai biroului (id, nume) pentru assigned_to_user_id / responsible_user_id. Cu q (un nume așa cum a fost auzit; diacriticele, majusculele/minusculele și micile greșeli de tastare sunt tolerate) răspunde cu statusul exact/similar/none ca instrumentele de rezolvare: doar "exact" este sigur de folosit direct.

Domeniu
colleagues:read

Parametri de interogare

q
stringcel mult 255 caractere

Numele unui coleg de căutat, așa cum a fost auzit sau dictat, în orice ordine a cuvintelor. Omiteți-l pentru a lista fiecare coleg activ.

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

Numărul maxim de colegi de returnat (implicit 200).

Implicit: 200

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
status
string | null

Doar cu q: exact = o singură potrivire sigură (id-ul ei se poate folosi în siguranță), similar = potrivire aproximativă sau mai multe potriviri (confirmați mai întâi cu utilizatorul), none = nicio potrivire (întrebați utilizatorul). Null fără q.

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

Colegi activi, cea mai bună potrivire prima cu q, altfel după nume.

Câmpurile colleagues
id
integer

Id-ul utilizatorului: transmiteți-l ca assigned_to_user_id / responsible_user_id.

name
string

Numele afișat așa cum îl arată Flowyer (cu titlul, dacă există).

title
string | null

Prefixul numelui, precum "Dr.", sau null.

total
integer

Câți colegi au corespuns (toți colegii activi fără q) înainte ca lista să fie redusă la limit.

truncated
boolean

True când au corespuns mai mulți colegi decât au fost returnați: restrângeți q sau măriți limit.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

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

Dosare

Listați dosarele

GET /api/agent/matters

Listează dosarele (cazurile) pe care utilizatorul le poate vedea, cele mai noi primele. Folosiți această operație pentru a găsi un dosar după numărul de caz, obiect sau client înainte de a-l referi în altă parte. Dosarele arhivate sunt ascunse, cu excepția cazului în care include_archived este true.

Domeniu
matters:read
Permisiune Flowyer
cases:read

Parametri de interogare

q
stringcel mult 100 caractere

Căutare text liber în obiect și în numele clienților (ignorând diacriticele și majusculele) și în celelalte numere de caz ale biroului; sau un număr de caz, fie exact așa cum este returnat în case_number (schema de numerotare a biroului), fie sub forma an/secvență, precum "2026/0025".

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

Doar dosarele acestui client.

Exemplu: 512
responsible_user_id
integer>= 1

Doar dosarele de care răspunde acest utilizator (id-urile din colleagues.list): ca responsabil principal, ca responsabil suplimentar sau ca membru al unui grup de lucru responsabil (la fel ca filtrul de colegi din interfața web).

updated_since
string <date-time>

Doar dosarele modificate la acest moment sau după el (ISO 8601).

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

Include dosarele arhivate.

Implicit: false
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Găsiți un dosar după nume

GET /api/agent/matters/resolve

Găsește un dosar după un obiect sau un nume de client rostit sau scris greșit (tolerând diacriticele, majusculele și micile greșeli de scriere). Returnează status-ul exact/similar/none și candidații. Doar "exact" este sigur de folosit direct; altfel confirmați cu utilizatorul. Multe potriviri aparente nu sunt niciodată "exact": restrângeți cu client_id sau cu un nume mai complet.

Domeniu
matters:read
Permisiune Flowyer
cases:read

Parametri de interogare

nameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Obiectul dosarului sau numele clientului de căutat, așa cum a fost auzit sau dictat.

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

Doar dosarele acestui client (folosiți după ce clients.resolve a returnat un client exact).

limit
integer>= 1<= 10

Numărul maxim de candidați de returnat (implicit 5).

Implicit: 5

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
status
string

exact = o singură potrivire sigură (id-ul ei poate fi folosit în siguranță). similar = una sau mai multe potriviri aproximative, confirmați mai întâi cu utilizatorul. none = nicio potrivire, întrebați utilizatorul.

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

Dosarele candidate, cea mai bună potrivire prima.

Câmpurile matters
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Câte dosare s-au potrivit înainte ca lista să fie restrânsă la limit.

truncated
boolean

True atunci când s-au potrivit mai multe dosare decât au fost returnate sau au existat prea multe potriviri aparente pentru a le verifica pe toate; restrângeți cu client_id sau cu un nume mai complet, ori măriți limit, în loc să alegeți dintr-o listă incompletă.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obțineți un dosar

GET /api/agent/matters/{id}

Returnează un dosar (caz) împreună cu clienții și detaliile lui. Răspunde cu 404 atunci când dosarul nu există sau utilizatorul nu îl poate vedea.

Domeniu
matters:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Ziua în care dosarul a fost arhivat, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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ți un dosar

POST /api/agent/matters

Deschide un dosar (caz) cu următorul număr de caz al anului. Necesită cel puțin un client existent (găsiți-l sau creați-l mai întâi). Avocatul responsabil este implicit utilizatorul cheii și este notificat în caz contrar. Părțile, persoanele de contact și onorariile se stabilesc în Flowyer.

Domeniu
matters:create
Permisiune Flowyer
cases:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

subjectobligatoriu
stringcel puțin 2 caracterecel mult 255 caractere

Titlu scurt al dosarului, așa cum apare în liste. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Kovács Kft. v. Nagy Bt. - contract dispute"
case_type_idobligatoriu
integer>= 1

Id-ul tipului de caz (domeniu de drept) din lista globală de tipuri de caz Flowyer: alegeți-l pe cel al cărui nume corespunde cuvintelor utilizatorului sau cereți utilizatorului să aleagă după nume. Un id necunoscut răspunde cu 422 și details.known_case_types (id + denumire localizată); un dosar existent își arată tipul în matters.get, în case_type_id / case_type.

client_idsobligatoriu
integer[]cel puțin 1 elementecel mult 20 elemente

Id-urile clienților (mandanților). Cel puțin unul, cel mult 20.

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

Avocat responsabil: un id de utilizator din colleagues.list (căutați acolo un nume dictat). Implicit: utilizatorul din spatele cheii.

started_on
string <date> | null

Data de început, YYYY-MM-DD. Implicit: astăzi.

Exemplu: "2026-10-29"
description
string | nullcel mult 10000 caractere

Descriere mai amplă, text simplu.

main_case_number
string | nullcel mult 100 caractere

Numărul de referință principal propriu al biroului pentru dosar. Obligatoriu atunci când schema de numerotare a biroului îl folosește (altfel API-ul răspunde cu 422).

restricted
boolean

true = doar avocații responsabili pot vedea dosarul (zid chinezesc).

Implicit: false
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Ziua în care dosarul a fost arhivat, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Ziua în care dosarul a fost arhivat, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizați un dosar

PATCH /api/agent/matters/{id}

Modifică obiectul, descrierea, data de început, indicatorul de litigiu sau avocatul responsabil al unui dosar. Numărul de caz, zidul chinezesc, starea de arhivare, onorariile și legăturile cu clienții nu pot fi editate aici. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409.

Domeniu
matters:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

subject
string | nullcel puțin 1 caractere

Titlu scurt al dosarului. Text simplu, cel mult 255 de caractere ca valoare NOUĂ; nici "<" și ">" nu pot fi introduse, însă un obiect stocat care este mai lung sau le conține poate fi returnat neschimbat. null păstrează obiectul curent.

description
string | null

Descriere mai amplă, text simplu, cel mult 10000 de caractere ca valoare NOUĂ; o descriere stocată mai lungă poate fi returnată neschimbată.

started_on
string <date> | null

Data de început, YYYY-MM-DD. null păstrează valoarea curentă (o dată de început nu poate fi eliminată).

litigious
boolean

Dacă dosarul este litigios sau nu.

responsible_user_id
integer | null>= 0

Nou avocat responsabil: id-ul de utilizator al unui coleg activ din colleagues.list. Acesta este notificat atunci când nu sunteți dumneavoastră. Trimiterea celui curent - sau null / 0, valoare sub care este citit un dosar fără responsabil - nu schimbă nimic.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul dosarului. Folosiți-l ca matter_id în altă parte.

Exemplu: 1234
case_number
string

Numărul de caz așa cum este afișat în Flowyer, în schema de numerotare a biroului.

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

Denumirea localizată a tipului de caz.

responsible_user_id
integer | null
responsible
string | null

Numele afișat al avocatului responsabil.

clients
object[]

Clienții (mandanții) dosarului.

Câmpurile clients
id
integer
name
string
started_on
string <date> | null
restricted
boolean

True atunci când doar avocații responsabili pot vedea dosarul (zid chinezesc).

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

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Ziua în care dosarul a fost arhivat, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Listare responsabili ai dosarului

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

Listează responsabilii SUPLIMENTARI ai unui dosar (responsabilul principal se află în matters.get): fiecare este un coleg (type "user", user_id setat) sau un grup de lucru (type "workgroup", workgroup_id setat), toți putând vedea dosarul. Răspunde cu 404 când dosarul nu este vizibil.

Domeniu
matters:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
type
string

"user" = un singur coleg; "workgroup" = fiecare membru al unui grup de lucru.

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

Id-ul de utilizator al colegului pentru o intrare "user" (transmiteți-l ca user_id către matters.responsibles.add); null pentru un grup de lucru.

workgroup_id
integer | null

Id-ul grupului de lucru pentru o intrare "workgroup"; null pentru un singur coleg. Responsabilii de tip grup de lucru sunt gestionați în Flowyer.

name
string | null

Numele afișat al colegului sau al grupului de lucru.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

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

Adăugare responsabil de dosar

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

Adaugă un coleg (user_id din colleagues.list) ca responsabil suplimentar al unui dosar. Acest lucru ÎI ACORDĂ acelui coleg acces la dosar, așa că adăugați doar pe cineva care ar trebui să îl vadă; acesta este notificat. Idempotent: readăugarea unui responsabil existent nu face nicio modificare.

Domeniu
matters:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Dosarul de care colegul devine responsabil (trebuie să fie vizibil).

Exemplu: 1234

Corpul cererii application/json

user_idobligatoriu
integer>= 1

Colegul de adăugat: un id de utilizator din colleagues.list. Adăugarea lui îi acordă acces la dosar.

Exemplu: 42

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
user_id
integer

Colegul acum responsabil de dosar.

name
string | null

Numele afișat al colegului.

already_responsible
boolean

True când colegul era deja responsabil al dosarului (nimic nu s-a schimbat).

notified
boolean

True când colegul a fost notificat că a fost adăugat. Niciodată true când colegul sunteți dumneavoastră sau când era deja responsabil.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

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

Clienți

Listare clienți

GET /api/agent/clients

Listează clienții biroului (persoane și companii), în ordine alfabetică; q caută în nume (ignorând diacriticele și majusculele/minusculele), e-mail și codul fiscal. Înainte de a crea un client, verificați numele cu clients.resolve (tolerează și greșelile de tastare). Clienții arhivați sunt ascunși, cu excepția cazului în care include_archived este true.

Domeniu
clients:read
Permisiune Flowyer
contacts:read

Parametri de interogare

q
stringcel mult 100 caractere

Caută în nume (ignorând diacriticele și majusculele/minusculele), e-mail și codul fiscal.

Exemplu: "Kovács"
is_person
boolean

true = doar persoane fizice, false = doar companii.

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

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Rezolvare client după nume

GET /api/agent/clients/resolve

Găsește un client după un nume rostit sau scris greșit (diacriticele, majusculele/minusculele și micile greșeli de tastare sunt tolerate). Returnează statusul exact/similar/none și clienții candidați. Doar "exact" este sigur de folosit direct; la "similar" sau "none" întrebați utilizatorul. Un nume cu multe asemănări nu este niciodată "exact": cereți un nume mai complet.

Domeniu
clients:read
Permisiune Flowyer
contacts:read

Parametri de interogare

nameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Numele clientului de căutat, așa cum a fost auzit sau dictat.

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

Numărul maxim de candidați de returnat (implicit 5).

Implicit: 5

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
status
string

exact = o singură potrivire sigură (id-ul ei poate fi folosit în siguranță). similar = una sau mai multe potriviri aproximative, confirmați mai întâi cu utilizatorul. none = nicio potrivire, întrebați utilizatorul.

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

Clienți candidați, cea mai bună potrivire prima.

Câmpurile matches
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Câți clienți au corespuns înainte ca lista să fie redusă la limit.

truncated
boolean

True când au corespuns mai mulți clienți decât au fost returnați, sau au existat prea multe asemănări pentru a le verifica pe toate; cereți utilizatorului un nume mai complet sau măriți limit în loc să alegeți dintr-o listă incompletă.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obținere client

GET /api/agent/clients/{id}

Returnează un client cu detaliile de adresă și de înregistrare. Numerele actelor de identitate și setările de onorariu nu sunt returnate niciodată.

Domeniu
clients:read
Permisiune Flowyer
contacts:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul clientului.

Exemplu: 512

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
tax_number
string | null

Doar pentru companii; null pentru o persoană fizică.

company_registration_number
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_name
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_position
string | null

Doar pentru companii; null pentru o persoană fizică.

main_activity
string | null

Obiectul principal de activitate. Doar pentru companii; null pentru o persoană fizică.

nationality_country
string | null
note
string | null
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
  }
}

Creare client

POST /api/agent/clients

Creează un client (persoană sau companie), înregistrat ca fiind creat de utilizatorul cheii. Verificați mai întâi numele cu clients.resolve (tolerează lipsa diacriticelor și greșelile de tastare): un 409 surprinde doar un client activ cu exact același nume, cu excepția cazului în care allow_duplicate_name este true. Numerele de act de identitate și onorariile nu pot fi setate.

Domeniu
clients:create
Permisiune Flowyer
contacts:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

nameobligatoriu
stringcel puțin 2 caracterecel mult 255 caractere

Numele complet al persoanei sau denumirea companiei. Text simplu; "<" și ">" nu sunt permise.

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

true pentru o persoană fizică, false (implicit) pentru o companie.

Implicit: false
email
string | nullcel mult 190 caractere
Exemplu: "info@kovacskft.hu"
phone
string | nullcel mult 64 caractere
Exemplu: "+36 1 234 5678"
address
object | null

Adresa înregistrată / de domiciliu.

Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object | null
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
tax_number
string | nullcel mult 64 caractere

Codul fiscal al companiei (doar pentru companii).

Exemplu: "12345678-2-41"
company_registration_number
string | nullcel mult 64 caractere

Numărul de înregistrare al companiei (doar pentru companii).

Exemplu: "01-09-123456"
representative_name
string | nullcel mult 255 caractere

Doar pentru companii.

representative_position
string | nullcel mult 255 caractere

Doar pentru companii.

main_activity
string | nullcel mult 255 caractere

Obiectul principal de activitate (doar pentru companii).

nationality_country
string | nullcel mult 100 caractere
note
string | nullcel mult 4000 caractere
allow_duplicate_name
boolean

Creează chiar dacă există un client activ cu același nume.

Implicit: false
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
tax_number
string | null

Doar pentru companii; null pentru o persoană fizică.

company_registration_number
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_name
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_position
string | null

Doar pentru companii; null pentru o persoană fizică.

main_activity
string | null

Obiectul principal de activitate. Doar pentru companii; null pentru o persoană fizică.

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
tax_number
string | null

Doar pentru companii; null pentru o persoană fizică.

company_registration_number
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_name
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_position
string | null

Doar pentru companii; null pentru o persoană fizică.

main_activity
string | null

Obiectul principal de activitate. Doar pentru companii; null pentru o persoană fizică.

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Există un client activ cu același nume (client_exists, sau client_exists_generic fără scope-ul clients:read, când clientul existent nu poate fi numit; transmiteți allow_duplicate_name pentru a suprascrie), Idempotency-Key a fost folosită pentru alt tip de resursă (idempotency_key_reused), sau, fără o cheie, o cerere identică este în curs de procesare (duplicate_in_progress).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare client

PATCH /api/agent/clients/{id}

Modifică câmpurile de contact ale unui client (nume, e-mail, telefon, adresă, notă, naționalitate și reprezentantul/activitatea companiei). Numerele de act de identitate, codurile fiscale, onorariile și tipul persoană/companie nu pot fi editate aici. Transmiteți expected_updated_at; o modificare conflictuală răspunde cu 409.

Domeniu
clients:update
Permisiune Flowyer
contacts:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

name
string | nullcel puțin 1 caractere

Numele complet sau denumirea companiei. Text simplu, cel mult 255 de caractere ca valoare NOUĂ; "<" și ">" nu pot fi introduse nici ele, dar un nume stocat care este mai lung sau le conține poate fi trimis înapoi nemodificat. null păstrează numele curent.

email
string | nullcel mult 190 caractere
phone
string | nullcel mult 64 caractere
address
object | null

Adresa înregistrată / de domiciliu.

Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object | null
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
representative_name
string | nullcel mult 255 caractere

Doar pentru companii.

representative_position
string | nullcel mult 255 caractere

Doar pentru companii.

main_activity
string | nullcel mult 255 caractere

Obiectul principal de activitate (doar pentru companii).

nationality_country
string | nullcel mult 100 caractere
note
string | null

Notă cu text liber, cel mult 4000 de caractere ca valoare NOUĂ; o notă stocată mai lungă poate fi trimisă înapoi nemodificată. null șterge nota.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul clientului. Folosiți-l ca client_id în altă parte.

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

True pentru o persoană fizică, false pentru o companie.

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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
address
object
Câmpurile address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
mailing_address
object
Câmpurile mailing_address
zip
string | nullcel mult 20 caractere
city
string | nullcel mult 100 caractere
street
string | nullcel mult 255 caractere
tax_number
string | null

Doar pentru companii; null pentru o persoană fizică.

company_registration_number
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_name
string | null

Doar pentru companii; null pentru o persoană fizică.

representative_position
string | null

Doar pentru companii; null pentru o persoană fizică.

main_activity
string | null

Obiectul principal de activitate. Doar pentru companii; null pentru o persoană fizică.

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Sarcini

Listare sarcini

GET /api/agent/tasks

Listează sarcinile (lucruri de făcut cu termen limită) pe care utilizatorul le poate vedea, cel mai apropiat termen limită primul. Sarcinile deschise în mod implicit; filtrați după responsabil, dosar, client sau interval de termene.

Domeniu
tasks:read
Permisiune Flowyer
tasks:read

Parametri de interogare

status
string

open (implicit), closed sau all.

Valori permise: "open" "closed" "all"
Implicit: "open"
assigned_to_user_id
integer>= 1

Doar sarcinile atribuite acestui utilizator (un id de utilizator din colleagues.list).

matter_id
integer>= 1

Doar sarcinile acestui dosar.

client_id
integer>= 1

Doar sarcinile fără dosar ale acestui client.

deadline_from
string <date>

Termen limită la această dată sau ulterior.

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

Termen limită la această dată sau anterior.

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

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obținere sarcină

GET /api/agent/tasks/{id}

Returnează o sarcină. Răspunde cu 404 când sarcina nu există sau utilizatorul nu o poate vedea.

Domeniu
tasks:read
Permisiune Flowyer
tasks:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul sarcinii.

Exemplu: 9876

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
    }
  }
}

Creare sarcină

POST /api/agent/tasks

Creează o sarcină (ceva de făcut cu termen limită), fie pe un dosar (matter_id, vizibil și nearhivat), fie fără dosar, opțional pentru un client (client_id). Responsabilul este implicit utilizatorul cheii și este notificat când este altcineva.

Domeniu
tasks:create
Permisiune Flowyer
tasks:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

subjectobligatoriu
stringcel puțin 2 caracterecel mult 1000 caractere

Ce trebuie făcut. Text simplu.

Exemplu: "Submit the statement of defence"
deadlineobligatoriu
string <date>

Data scadentă, YYYY-MM-DD.

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

Dosarul de care aparține sarcina. Omiteți pentru o sarcină fără dosar.

Exemplu: 1234
client_id
integer | null>= 1

Clientul unei sarcini fără dosar. Nu este permis împreună cu matter_id (o sarcină de pe un dosar preia clientul dosarului).

assigned_to_user_id
integer | null>= 1

Colegul responsabil de sarcină: un id de utilizator din colleagues.list (căutați acolo un nume dictat). Implicit: utilizatorul din spatele cheii.

priority
integer>= 1<= 3

1 = scăzută, 2 = medie (implicit), 3 = ridicată.

Implicit: 2
description
string | nullcel mult 10000 caractere

Detalii mai ample, text simplu.

flag_id
integer | null>= 1

Id-ul unui indicator (etichetă) de sarcină al biroului.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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
}'

Exemple de răspuns

{
  "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
}

Actualizare sarcină

PATCH /api/agent/tasks/{id}

Modifică o sarcină: subiectul, termenul limită, descrierea, prioritatea, indicatorul, responsabilul sau dosarul de care aparține. Mutarea ei pe un dosar re-derivă legătura cu instanța și elimină un client direct; client_id este doar pentru o sarcină fără dosar. Transmiteți expected_updated_at; o modificare conflictuală răspunde cu 409.

Domeniu
tasks:update
Permisiune Flowyer
tasks:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

subject
string | nullcel puțin 1 caractere

Ce trebuie făcut. Text simplu, cel mult 1000 de caractere ca valoare NOUĂ; un subiect stocat mai lung poate fi trimis înapoi nemodificat. null păstrează subiectul curent.

deadline
string <date> | null

Data scadentă, YYYY-MM-DD. null păstrează termenul limită curent (un termen limită nu poate fi șters).

matter_id
integer | null>= 1

Mută sarcina pe acest dosar (trebuie să fie vizibil și nearhivat), sau null pentru a o detașa. Trimiterea dosarului curent al sarcinii nu schimbă nimic.

client_id
integer | null>= 1

Clientul unei sarcini fără dosar. Permis doar când sarcina nu are dosar.

assigned_to_user_id
integer | null>= 0

Noul responsabil: id-ul de utilizator al unui coleg activ din colleagues.list. Notificat când nu sunteți dumneavoastră. Trimiterea celui curent, sau null / 0, cu care o sarcină fără responsabil este citită înapoi, nu schimbă nimic.

priority
integer>= 1<= 3

1 = scăzută, 2 = medie, 3 = ridicată. Omiteți pentru a păstra prioritatea curentă (inclusiv când sarcina este citită înapoi cu priority null); null este respins.

description
string | null

Detalii mai ample, text simplu, cel mult 10000 de caractere ca valoare NOUĂ; o descriere stocată mai lungă poate fi trimisă înapoi nemodificată.

flag_id
integer | null>= 1

Id-ul unui indicator (etichetă) de sarcină al biroului, sau null pentru a-l șterge.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Închidere sarcină

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

Închide o sarcină. Dacă sunt furnizate minute, înregistrează și o intrare de timp (necesită workhours:create și un dosar: cel propriu al sarcinii, sau matter_id pe o sarcină fără dosar); minutele facturabile sunt limitate la plafonul orar al biroului. O a doua închidere răspunde cu 409, astfel încât o reîncercare nu înregistrează niciodată o a doua intrare.

Domeniu
tasks:update
Permisiune Flowyer
tasks:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul sarcinii.

Exemplu: 9876

Corpul cererii application/json

minutes_spent
integer | null>= 0<= 100000

Timpul petrecut, în minute. Înregistrarea oricărui timp necesită scope-ul workhours:create și un dosar.

minutes_invoiceable
integer | null>= 0<= 100000

Minute facturabile; limitate la plafonul orar al biroului.

minutes_normative
integer | null>= 0<= 100000

Minute normative; stocate brut, niciodată plafonate.

matter_id
integer | null>= 1

Atribuie acest dosar unei sarcini FĂRĂ DOSAR la închidere (și astfel face posibilă înregistrarea timpului). Nu este permis când sarcina are deja un dosar.

client_id
integer | null>= 1

Clientul direct (Megbízó) pentru o sarcină fără dosar, închisă fără un dosar.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
subject
string
Exemplu: "Submit the statement of defence"
description
string | null
deadline
string <date> | null

Data scadentă, YYYY-MM-DD.

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

1 = scăzută, 2 = medie, 3 = ridicată; null = nesetată (o sarcină mai veche fără prioritate).

Exemplu: 2
status
string
Valori permise: "open" "closed"
closed_at
string <date> | null

Ziua în care a fost închisă sarcina, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

matter
object | null

Dosarul de care aparține sarcina, dacă există.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul: primul client al dosarului, sau clientul propriu al sarcinii când aceasta nu are dosar.

Câmpurile 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
Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Intrarea de timp efectuată la închidere, sau null când nu a fost introdus timp.

Câmpurile booked_workhour
id
integer>= 1
minutes
integer
minutes_invoiceable
integer
minutes_normative
integer
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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 lucrate

Listare intrări de timp

GET /api/agent/workhours

Listează intrările de timp curente (încă nefacturate) de pe dosarele pe care utilizatorul le poate vedea, cele mai noi primele. Filtrați după dosar, coleg responsabil sau interval de date. Intrările excluse din rezumat sunt și ele listate, marcate cu excluded: true; lăsați-le în afara totalurilor facturabile.

Domeniu
workhours:read
Permisiune Flowyer
workhours:read

Parametri de interogare

matter_id
integer>= 1

Doar intrările de pe acest dosar.

Exemplu: 1234
responsible_user_id
integer>= 1

Doar intrările atribuite acestui coleg (un id de utilizator din colleagues.list).

date_from
string <date>

Doar intrările de la această dată sau ulterioare (YYYY-MM-DD).

date_to
string <date>

Doar intrările de la această dată sau anterioare (YYYY-MM-DD).

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul intrării de timp.

matter_id
integer | null

Dosarul pe care este înregistrată intrarea.

date
string <date> | null
activity
string | null

Ce s-a făcut (text simplu).

minutes
integer | null

Minute petrecute.

minutes_invoiceable
integer | null

Minute facturabile după aplicarea plafonului orar al biroului (pot fi mai mici decât cele solicitate). Contează la facturare doar cât timp excluded este false.

minutes_normative
integer | null

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null

Colegul pe care este înregistrat timpul.

responsible
string | null
recorded_by_user_id
integer | null

Cine a înregistrat intrarea.

locked
boolean

True când intrarea este blocată (doar pentru citire prin API).

excluded
boolean

True când un coleg a exclus intrarea din rezumatul dosarului: nu este facturată și minutele ei sunt lăsate în afara totalurilor facturabile.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obținere intrare de timp

GET /api/agent/workhours/{id}

Returnează o intrare de timp curentă după id, dacă dosarul său este vizibil pentru utilizator.

Domeniu
workhours:read
Permisiune Flowyer
workhours:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul intrării de timp.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării de timp.

matter_id
integer | null

Dosarul pe care este înregistrată intrarea.

date
string <date> | null
activity
string | null

Ce s-a făcut (text simplu).

minutes
integer | null

Minute petrecute.

minutes_invoiceable
integer | null

Minute facturabile după aplicarea plafonului orar al biroului (pot fi mai mici decât cele solicitate). Contează la facturare doar cât timp excluded este false.

minutes_normative
integer | null

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null

Colegul pe care este înregistrat timpul.

responsible
string | null
recorded_by_user_id
integer | null

Cine a înregistrat intrarea.

locked
boolean

True când intrarea este blocată (doar pentru citire prin API).

excluded
boolean

True când un coleg a exclus intrarea din rezumatul dosarului: nu este facturată și minutele ei sunt lăsate în afara totalurilor facturabile.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
  }
}

Înregistrare intrare de timp

POST /api/agent/workhours

Înregistrează o intrare de timp pe un dosar: dată, activitate, minute petrecute și minute facturabile. Minutele facturabile omise înseamnă nefacturabil: trimiteți minutes_invoiceable pentru munca facturabilă. Ele sunt limitate la plafonul orar al biroului. Colegul responsabil este implicit utilizatorul cheii și este notificat în caz contrar.

Domeniu
workhours:create
Permisiune Flowyer
workhours:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

matter_idobligatoriu
integer>= 1

Dosarul pe care este înregistrat timpul (trebuie să fie vizibil).

Exemplu: 1234
dateobligatoriu
string <date>

Data lucrării, YYYY-MM-DD.

Exemplu: "2026-10-30"
subject
stringcel puțin 2 caracterecel mult 1000 caractere

Ce s-a făcut; partea de citire o returnează ca activity și oricare dintre denumiri este acceptată aici (una dintre cele două este obligatorie). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Drafting the statement of claim"
activity
stringcel puțin 2 caracterecel mult 1000 caractere

Același câmp ca subject, sub denumirea folosită de partea de citire. Trimiteți una dintre cele două.

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

Minute efectiv petrecute.

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

Minute facturabile solicitate. Omise sau null = nefacturabil (intrarea nu facturează nimic; nu sunt derivate din minute): pentru munca facturabilă trimiteți-le explicit, de obicei egale cu minutele. Plafonul orar al biroului poate reduce valoarea stocată. Contează la facturare doar cât timp intrarea nu este exclusă din rezumat.

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

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null>= 1

Colegul pe care este înregistrat timpul: un id de utilizator din colleagues.list (căutați acolo un nume dictat). Implicit: utilizatorul din spatele cheii.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării de timp.

matter_id
integer | null

Dosarul pe care este înregistrată intrarea.

date
string <date> | null
activity
string | null

Ce s-a făcut (text simplu).

minutes
integer | null

Minute petrecute.

minutes_invoiceable
integer | null

Minute facturabile după aplicarea plafonului orar al biroului (pot fi mai mici decât cele solicitate). Contează la facturare doar cât timp excluded este false.

minutes_normative
integer | null

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null

Colegul pe care este înregistrat timpul.

responsible
string | null
recorded_by_user_id
integer | null

Cine a înregistrat intrarea.

locked
boolean

True când intrarea este blocată (doar pentru citire prin API).

excluded
boolean

True când un coleg a exclus intrarea din rezumatul dosarului: nu este facturată și minutele ei sunt lăsate în afara totalurilor facturabile.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării de timp.

matter_id
integer | null

Dosarul pe care este înregistrată intrarea.

date
string <date> | null
activity
string | null

Ce s-a făcut (text simplu).

minutes
integer | null

Minute petrecute.

minutes_invoiceable
integer | null

Minute facturabile după aplicarea plafonului orar al biroului (pot fi mai mici decât cele solicitate). Contează la facturare doar cât timp excluded este false.

minutes_normative
integer | null

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null

Colegul pe care este înregistrat timpul.

responsible
string | null
recorded_by_user_id
integer | null

Cine a înregistrat intrarea.

locked
boolean

True când intrarea este blocată (doar pentru citire prin API).

excluded
boolean

True când un coleg a exclus intrarea din rezumatul dosarului: nu este facturată și minutele ei sunt lăsate în afara totalurilor facturabile.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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
}'

Exemple de răspuns

{
  "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
}

Actualizare intrare de timp

PATCH /api/agent/workhours/{id}

Modifică o intrare de timp curentă: dată, activitate (subject sau activity), minute, minute facturabile (un număr modificat este limitat la plafonul orar, unul retrimis identic este păstrat) și colegul responsabil. O intrare blocată sau facturată nu poate fi modificată (409). Transmiteți expected_updated_at; un conflict răspunde cu 409.

Domeniu
workhours:update
Permisiune Flowyer
workhours:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

date
string <date> | null

Data lucrării, YYYY-MM-DD. null păstrează data curentă.

subject
string | nullcel puțin 1 caractere

Ce s-a făcut, valoarea pe care partea de citire o returnează ca activity (oricare dintre denumiri este acceptată; null sub una dintre ele înseamnă "neprecizat", doar două texte diferite sunt respinse). Text simplu, cel mult 1000 de caractere ca valoare NOUĂ; "<" și ">" nu pot fi introduse nici ele, dar un text stocat care este mai lung sau le conține poate fi trimis înapoi nemodificat. null păstrează textul curent.

activity
string | nullcel puțin 1 caractere

Același câmp ca subject, sub denumirea folosită de partea de citire. Trimiteți una dintre cele două (null sub cealaltă este acceptabil).

minutes
integer | null>= 0<= 100000

Minute efectiv petrecute; null le șterge.

minutes_invoiceable
integer | null>= 0<= 100000

Minute facturabile solicitate. Un număr diferit de cel stocat este limitat la cât a mai rămas din plafonul orar; retrimiterea valorii returnate de citire o păstrează așa cum a fost înregistrată (nu este limitată din nou). null le șterge. Contează la facturare doar cât timp intrarea nu este exclusă din rezumat (excluded este false).

minutes_normative
integer | null>= 0<= 100000

Minute normative (niciodată plafonate); null le șterge.

responsible_user_id
integer | null>= 0

Noul coleg responsabil: id-ul de utilizator al unui coleg activ din colleagues.list; notificat când nu sunteți dumneavoastră. Trimiterea celui curent, sau null / 0, cu care o intrare fără responsabil este citită înapoi, nu schimbă nimic.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării de timp.

matter_id
integer | null

Dosarul pe care este înregistrată intrarea.

date
string <date> | null
activity
string | null

Ce s-a făcut (text simplu).

minutes
integer | null

Minute petrecute.

minutes_invoiceable
integer | null

Minute facturabile după aplicarea plafonului orar al biroului (pot fi mai mici decât cele solicitate). Contează la facturare doar cât timp excluded este false.

minutes_normative
integer | null

Minute normative (informative; niciodată plafonate).

responsible_user_id
integer | null

Colegul pe care este înregistrat timpul.

responsible
string | null
recorded_by_user_id
integer | null

Cine a înregistrat intrarea.

locked
boolean

True când intrarea este blocată (doar pentru citire prin API).

excluded
boolean

True când un coleg a exclus intrarea din rezumatul dosarului: nu este facturată și minutele ei sunt lăsate în afara totalurilor facturabile.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a modificat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at), sau a fost facturată / blocată și nu mai poate fi modificată prin API (record_locked; efectuați modificarea în Flowyer).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Costuri

Listare costuri

GET /api/agent/costs

Listează costurile curente ale dosarelor pe care utilizatorul le poate vedea, cele mai noi primele (un cost facturat nu mai apare aici). Filtrați după dosar, coleg responsabil sau interval de date. Sumele sunt nete. Rândurile marcate cu excluded: true sunt în afara rezumatului, iar rândurile marcate cu locked: true sunt gestionate de Flowyer.

Domeniu
costs:read
Permisiune Flowyer
cases:read, summary:read

Parametri de interogare

matter_id
integer>= 1

Doar costurile de pe acest dosar.

Exemplu: 1234
responsible_user_id
integer>= 1

Doar costurile înregistrate pentru acest coleg (un id de utilizator din colleagues.list).

date_from
string <date>

Doar costurile de la această dată sau ulterioare (YYYY-MM-DD).

date_to
string <date>

Doar costurile de la această dată sau anterioare (YYYY-MM-DD).

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul costului.

matter_id
integer | null

Dosarul de care aparține costul.

date
string <date> | null
activity
string | null

Descrierea costului (text simplu).

cost
number | null

Suma netă a costului (fără TVA).

cost_invoiceable
number | null

Suma netă de facturat mai departe către client. Contează la facturare doar cât timp excluded este false.

currency_id
integer | null

Id-ul monedei (lista de monede Flowyer).

currency
string | null

Codul ISO al monedei, de ex. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True când un coleg a exclus costul din rezumatul dosarului: nu este facturat și este lăsat în afara totalurilor facturabile.

locked
boolean

True când costul este gestionat de Flowyer, preluat dintr-o factură primită sau un supliment de debursare, și nu poate fi modificat prin API (costs.update răspunde cu 409 record_locked, details.reason indică motivul).

approved_for_billing
boolean

True când un coleg a aprobat costul pentru facturare în rezumatul dosarului. Rămâne editabil prin API (ca în interfața web), iar aprobarea NU este solicitată din nou ulterior: menționați acest lucru înainte de a modifica suma unui cost aprobat.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obținere cost

GET /api/agent/costs/{id}

Returnează un cost curent după id, dacă dosarul său este vizibil pentru utilizator. Sumele sunt nete.

Domeniu
costs:read
Permisiune Flowyer
cases:read, summary:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul costului.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul costului.

matter_id
integer | null

Dosarul de care aparține costul.

date
string <date> | null
activity
string | null

Descrierea costului (text simplu).

cost
number | null

Suma netă a costului (fără TVA).

cost_invoiceable
number | null

Suma netă de facturat mai departe către client. Contează la facturare doar cât timp excluded este false.

currency_id
integer | null

Id-ul monedei (lista de monede Flowyer).

currency
string | null

Codul ISO al monedei, de ex. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True când un coleg a exclus costul din rezumatul dosarului: nu este facturat și este lăsat în afara totalurilor facturabile.

locked
boolean

True când costul este gestionat de Flowyer, preluat dintr-o factură primită sau un supliment de debursare, și nu poate fi modificat prin API (costs.update răspunde cu 409 record_locked, details.reason indică motivul).

approved_for_billing
boolean

True când un coleg a aprobat costul pentru facturare în rezumatul dosarului. Rămâne editabil prin API (ca în interfața web), iar aprobarea NU este solicitată din nou ulterior: menționați acest lucru înainte de a modifica suma unui cost aprobat.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
  }
}

Înregistrare cost

POST /api/agent/costs

Înregistrează un cost (debursare) pe un dosar: dată, text (subject, citit înapoi ca activity), suma netă, suma netă facturată clientului și moneda (implicit: moneda biroului). Sumele sunt nete (fără TVA). Colegul responsabil este implicit utilizatorul cheii și este notificat în caz contrar.

Domeniu
costs:create
Permisiune Flowyer
cases:create, summary:read

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

matter_idobligatoriu
integer>= 1

Dosarul de care aparține costul (trebuie să fie vizibil).

Exemplu: 1234
dateobligatoriu
string <date>

Data costului, YYYY-MM-DD.

Exemplu: "2026-10-30"
subject
stringcel puțin 2 caracterecel mult 1000 caractere

Descrierea costului; partea de citire o returnează ca activity și oricare dintre denumiri este acceptată aici (una dintre cele două este obligatorie). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Court filing fee"
activity
stringcel puțin 2 caracterecel mult 1000 caractere

Același câmp ca subject, sub denumirea folosită de partea de citire. Trimiteți una dintre cele două.

Model: ^[^<>]*$
costobligatoriu
integer>= 0<= 2147483647

Suma netă a costului (fără TVA), un număr întreg în unitatea principală a monedei (subunitățile nu sunt stocate).

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

Suma netă de facturat mai departe către client, un număr întreg (omiteți dacă nu se facturează). Contează la facturare doar cât timp costul nu este exclus din rezumat.

Exemplu: 15000
currency_id
integer | null>= 1

Id-ul monedei din lista de monede Flowyer (nu un cod ISO). Omiteți-l pentru a folosi moneda biroului (GET /me office.currency_id / office.currency); un id necunoscut răspunde cu 422, cu id-urile și codurile acceptate în details.allowed.

responsible_user_id
integer | null>= 1

Colegul responsabil: un id de utilizator din colleagues.list (căutați acolo un nume dictat). Implicit: utilizatorul din spatele cheii.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul costului.

matter_id
integer | null

Dosarul de care aparține costul.

date
string <date> | null
activity
string | null

Descrierea costului (text simplu).

cost
number | null

Suma netă a costului (fără TVA).

cost_invoiceable
number | null

Suma netă de facturat mai departe către client. Contează la facturare doar cât timp excluded este false.

currency_id
integer | null

Id-ul monedei (lista de monede Flowyer).

currency
string | null

Codul ISO al monedei, de ex. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True când un coleg a exclus costul din rezumatul dosarului: nu este facturat și este lăsat în afara totalurilor facturabile.

locked
boolean

True când costul este gestionat de Flowyer, preluat dintr-o factură primită sau un supliment de debursare, și nu poate fi modificat prin API (costs.update răspunde cu 409 record_locked, details.reason indică motivul).

approved_for_billing
boolean

True când un coleg a aprobat costul pentru facturare în rezumatul dosarului. Rămâne editabil prin API (ca în interfața web), iar aprobarea NU este solicitată din nou ulterior: menționați acest lucru înainte de a modifica suma unui cost aprobat.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul costului.

matter_id
integer | null

Dosarul de care aparține costul.

date
string <date> | null
activity
string | null

Descrierea costului (text simplu).

cost
number | null

Suma netă a costului (fără TVA).

cost_invoiceable
number | null

Suma netă de facturat mai departe către client. Contează la facturare doar cât timp excluded este false.

currency_id
integer | null

Id-ul monedei (lista de monede Flowyer).

currency
string | null

Codul ISO al monedei, de ex. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True când un coleg a exclus costul din rezumatul dosarului: nu este facturat și este lăsat în afara totalurilor facturabile.

locked
boolean

True când costul este gestionat de Flowyer, preluat dintr-o factură primită sau un supliment de debursare, și nu poate fi modificat prin API (costs.update răspunde cu 409 record_locked, details.reason indică motivul).

approved_for_billing
boolean

True când un coleg a aprobat costul pentru facturare în rezumatul dosarului. Rămâne editabil prin API (ca în interfața web), iar aprobarea NU este solicitată din nou ulterior: menționați acest lucru înainte de a modifica suma unui cost aprobat.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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
}'

Exemple de răspuns

{
  "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
}

Actualizare cost

PATCH /api/agent/costs/{id}

Modifică un cost curent: text (subject, citit înapoi ca activity), dată, sume nete, moneda și colegul responsabil. Un cost marcat cu locked: true nu poate fi modificat (409 record_locked, details.reason). Transmiteți expected_updated_at; o modificare conflictuală răspunde cu 409.

Domeniu
costs:update
Permisiune Flowyer
cases:modify, summary:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

date
string <date> | null

Data costului, YYYY-MM-DD. null păstrează data curentă.

subject
string | nullcel puțin 1 caractere

Descrierea costului, valoarea pe care partea de citire o returnează ca activity (oricare dintre denumiri este acceptată; null sub una dintre ele înseamnă "neprecizat", doar două texte diferite sunt respinse). Text simplu, cel mult 1000 de caractere ca valoare NOUĂ; "<" și ">" nu pot fi introduse nici ele, dar un text stocat care este mai lung sau le conține poate fi trimis înapoi nemodificat. null păstrează textul curent.

activity
string | nullcel puțin 1 caractere

Același câmp ca subject, sub denumirea folosită de partea de citire. Trimiteți una dintre cele două (null sub cealaltă este acceptabil).

cost
integer | null>= 0<= 2147483647

Suma netă a costului (fără TVA), un număr întreg în unitatea principală a monedei (subunitățile nu sunt stocate). null șterge suma.

cost_invoiceable
integer | null>= 0<= 2147483647

Suma netă de facturat mai departe către client, un număr întreg; null o șterge. Contează la facturare doar cât timp costul nu este exclus din rezumat (excluded este false).

currency_id
integer | null>= 0

Id-ul monedei din lista de monede Flowyer (nu un cod ISO; moneda biroului este GET /me office.currency_id). Un id necunoscut răspunde cu 422, cu id-urile și codurile acceptate în details.allowed. null, sau 0-ul cu care un cost mai vechi nesetat este citit înapoi, păstrează moneda curentă.

responsible_user_id
integer | null>= 0

Noul coleg responsabil: id-ul de utilizator al unui coleg activ din colleagues.list. Trimiterea celui curent, sau null / 0, cu care un cost fără responsabil este citit înapoi, nu schimbă nimic.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul costului.

matter_id
integer | null

Dosarul de care aparține costul.

date
string <date> | null
activity
string | null

Descrierea costului (text simplu).

cost
number | null

Suma netă a costului (fără TVA).

cost_invoiceable
number | null

Suma netă de facturat mai departe către client. Contează la facturare doar cât timp excluded este false.

currency_id
integer | null

Id-ul monedei (lista de monede Flowyer).

currency
string | null

Codul ISO al monedei, de ex. HUF, EUR.

responsible_user_id
integer | null
responsible
string | null
excluded
boolean

True când un coleg a exclus costul din rezumatul dosarului: nu este facturat și este lăsat în afara totalurilor facturabile.

locked
boolean

True când costul este gestionat de Flowyer, preluat dintr-o factură primită sau un supliment de debursare, și nu poate fi modificat prin API (costs.update răspunde cu 409 record_locked, details.reason indică motivul).

approved_for_billing
boolean

True când un coleg a aprobat costul pentru facturare în rezumatul dosarului. Rămâne editabil prin API (ca în interfața web), iar aprobarea NU este solicitată din nou ulterior: menționați acest lucru înainte de a modifica suma unui cost aprobat.

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

Trimiteți această valoare înapoi ca expected_updated_at la actualizare.

updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a modificat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at), sau a fost facturată / blocată și nu mai poate fi modificată prin API (record_locked; efectuați modificarea în Flowyer).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Facturi

Listare facturi

GET /api/agent/invoices

Listează facturile (emise și primite), cea mai recentă dată de emitere prima. direction=outgoing este lista facturilor emise de birou și exclude proformele (direction=proforma le listează pe acelea). Doar pentru citire: facturile nu pot fi create sau modificate prin API. Facturile dosarelor pe care utilizatorul nu le poate vedea sunt ascunse.

Domeniu
invoices:read
Permisiune Flowyer
invoices:read, summary:read

Parametri de interogare

direction
string

Cele trei liste proprii ale biroului: outgoing = facturi emise de birou, proformele excluse (un rând mai vechi fără tip de document contează ca factură, ca în tabloul de bord al biroului); proforma = cereri de plată (díjbekérő) emise de birou; incoming = primite.

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

Data de emitere la această dată sau ulterioară.

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

Data de emitere la această dată sau anterioară.

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

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 301
invoice_number
string | null
Exemplu: "FLW-2026-0042"
direction
string | null

outgoing = emise de birou, incoming = primite de birou.

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

"proforma" este o cerere de plată, nu o factură emisă: nu este venit și nu trebuie contabilizată împreună cu cele emise. invoices.list direction=outgoing exclude proformele, direction=proforma le listează. Null pe un rând mai vechi, care contează ca factură.

Valori permise: "invoice" "proforma" "receipt"
source
string | null
Valori permise: "manual" "szamlazz_outgoing" "szamlazz_imported"
paid_status
string | null
Valori permise: "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
Exemplu: "HUF"
payment_method_id
integer | null
payment_method
string | null

Denumirea localizată a metodei de plată (de ex. transfer bancar); în engleză când limba biroului nu are o traducere pentru ea, null când metoda nu are deloc un nume. Identificați metoda după payment_method_id.

supplier
string | null

Emitentul unei facturi primite.

client
object | null
Câmpurile client
id
integer
name
string
matter_id
integer | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Obținere factură

GET /api/agent/invoices/{id}

Returnează o factură. Doar pentru citire. Răspunde cu 404 când nu există sau aparține unui dosar pe care utilizatorul nu îl poate vedea.

Domeniu
invoices:read
Permisiune Flowyer
invoices:read, summary:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul facturii.

Exemplu: 301

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 301
invoice_number
string | null
Exemplu: "FLW-2026-0042"
direction
string | null

outgoing = emise de birou, incoming = primite de birou.

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

"proforma" este o cerere de plată, nu o factură emisă: nu este venit și nu trebuie contabilizată împreună cu cele emise. invoices.list direction=outgoing exclude proformele, direction=proforma le listează. Null pe un rând mai vechi, care contează ca factură.

Valori permise: "invoice" "proforma" "receipt"
source
string | null
Valori permise: "manual" "szamlazz_outgoing" "szamlazz_imported"
paid_status
string | null
Valori permise: "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
Exemplu: "HUF"
payment_method_id
integer | null
payment_method
string | null

Denumirea localizată a metodei de plată (de ex. transfer bancar); în engleză când limba biroului nu are o traducere pentru ea, null când metoda nu are deloc un nume. Identificați metoda după payment_method_id.

supplier
string | null

Emitentul unei facturi primite.

client
object | null
Câmpurile 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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Documente

Listați documentele unui dosar

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

Listează versiunile curente ale documentelor arhivate sub un dosar: nume, dimensiuni, foldere și cine le-a încărcat. Doar metadate; folosiți documents.download (scope documents:download) pentru un link semnat către conținut. Documentele cu nume apar primele, în ordine alfabetică, apoi cele importate care nu au nume.

Domeniu
documents:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

q
stringcel mult 100 caractere

Filtrați după numele fișierului.

Exemplu: "contract"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
name
string

Numele fișierului așa cum este afișat în Flowyer: numele stocat împreună cu documentul sau numele de stocare al acestuia atunci când a fost importat dintr-un sistem mai vechi fără nume. documents.list este ordonat după numele stocat: documentele care au unul apar primele, în ordine alfabetică, apoi cele importate fără nume stocat, cele mai vechi primele (ordinea în care au fost arhivate în Flowyer), care, prin urmare, nu sunt sortate după numele afișat aici. Ordinea este aceeași pe fiecare pagină, astfel încât limit și offset parcurg lista fără repetări sau lacune.

Exemplu: "Contract_v2.docx"
size
integer | null

Octeți.

version
integer

Numărul versiunii curente a fișierului.

folder
object | null

Folderul în care este arhivat documentul sau null la rădăcina dosarului. documents.upload.complete răspunde cu null atunci când folderul ales la documents.upload.init a fost șters în timp ce octeții se încărcau: documentul este atunci arhivat la rădăcina dosarului, unde îl afișează Flowyer. Dacă rădăcina conține deja un document cu acel nume, încărcarea este arhivată sub un nume cu sufix ("Contract_2.pdf") în loc să devină o versiune nouă a acelui document fără legătură; răspunsul 201 reia name stocat.

Câmpurile folder
id
integer
name
string
path
string

Calea folderului în interiorul dosarului, separată prin "/".

folder_deleted
boolean

True atunci când documentul este arhivat într-un folder care nu mai există, lucru pe care lista de fișiere proprie a Flowyer nu îl afișează (folder este null pentru el, la fel ca pentru un document aflat la rădăcina dosarului). documents.upload.complete răspunde cu true doar dacă folderul a fost șters în timp ce octeții se încărcau ȘI mutarea fișierului stocat la rădăcina dosarului a eșuat: documentul este atunci păstrat în folderul șters, unde conținutul lui este încă accesibil. False pentru orice altceva, inclusiv o arhivare normală la rădăcină.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/matters/1234/documents?q=contract&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Listați folderele unui dosar

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

Listează fiecare folder al unui dosar, inclusiv cele goale: id, name, parent_id și calea separată prin "/", ordonate după cale. Transmiteți un id de folder ca folder_id către documents.upload.init. Răspunde cu 404 atunci când dosarul nu este vizibil pentru utilizator.

Domeniu
documents:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

q
stringcel mult 100 caractere

Doar folderele a căror cale conține acest text (ignorând majusculele și diacriticele), de exemplu un nume de folder.

Exemplu: "Beadványok"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul folderului: transmiteți-l ca folder_id către documents.upload.init.

name
string

Numele folderului așa cum este afișat în Flowyer.

parent_id
integer | null

Id-ul folderului părinte; null pentru un folder aflat la rădăcina dosarului.

path
string

Calea folderului în interiorul dosarului, separată prin "/", de exemplu "/Iratok/Beadványok" (aceeași cale pe care documents.list o afișează pentru folderul unui fișier).

updated_at
string <date-time> | null

Transmiteți aceasta către documents.folders.rename ca expected_updated_at.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/matters/1234/folders?q=Beadv%C3%A1nyok&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Creare folder de dosar

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

Creează un folder într-un dosar, la rădăcină sau sub parent_id (un folder al ACELUIAȘI dosar). Numele este text simplu ("<" și ">" nu sunt permise). Arhivați un document în el transmițând id-ul returnat ca folder_id către documents.upload.init. Răspunde cu 404 când dosarul nu este vizibil.

Domeniu
documents:create
Permisiune Flowyer
cases:create

Parametri de cale

idobligatoriu
integer>= 1

Dosarul de care aparține folderul (trebuie să fie vizibil).

Exemplu: 1234

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

nameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Numele folderului, cel mult 255 de caractere. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Beadványok"
parent_id
integer | null>= 1

Id-ul folderului părinte (din documents.folders) din interiorul ACELUIAȘI dosar; omiteți pentru un folder aflat la rădăcina dosarului.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul folderului: transmiteți-l ca folder_id către documents.upload.init, sau ca parent_id către documents.folders.create.

name
string

Numele folderului așa cum este afișat în Flowyer.

parent_id
integer | null

Id-ul folderului părinte; null pentru un folder aflat la rădăcina dosarului.

path
string

Calea folderului în interiorul dosarului, separată prin "/", de exemplu "/Iratok/Beadványok".

updated_at
string <date-time> | null

Transmiteți aceasta către documents.folders.rename ca expected_updated_at.

created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul folderului: transmiteți-l ca folder_id către documents.upload.init, sau ca parent_id către documents.folders.create.

name
string

Numele folderului așa cum este afișat în Flowyer.

parent_id
integer | null

Id-ul folderului părinte; null pentru un folder aflat la rădăcina dosarului.

path
string

Calea folderului în interiorul dosarului, separată prin "/", de exemplu "/Iratok/Beadványok".

updated_at
string <date-time> | null

Transmiteți aceasta către documents.folders.rename ca expected_updated_at.

created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "data": {
    "id": 1234,
    "name": "string",
    "parent_id": 1234,
    "path": "string",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "created": true
}

Începeți încărcarea unui document

POST /api/agent/matters/{id}/documents/uploads

Începe încărcarea unui document: returnează un upload_url semnat și un upload_token. Trimiteți octeții acolo prin PUT, apoi apelați documents.upload.complete. Operația PUT este o cerere HTTPS obișnuită în afara acestui API și în afara instrumentelor MCP: un asistent fără propriul client HTTP ar trebui să ceară utilizatorului să încarce fișierul în Flowyer.

Domeniu
documents:create
Permisiune Flowyer
cases:create

Parametri de cale

idobligatoriu
integer>= 1

Dosarul căruia îi aparține documentul (trebuie să fie vizibil).

Corpul cererii application/json

filenameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Numele fișierului cu extensie, de exemplu "Contract.pdf". Text simplu; "<" și ">" nu sunt permise. Tipurile de fișiere executabile și web sunt refuzate (422 blocked_file_type).

Model: ^[^<>]*$
Exemplu: "Contract.pdf"
content_typeobligatoriu
stringcel puțin 1 caracterecel mult 100 caractere

Tipul MIME trimis la operația PUT, de exemplu "application/pdf". Face parte din semnătură și trebuie să corespundă exact.

Exemplu: "application/pdf"
sizeobligatoriu
integer>= 1

Dimensiunea fișierului în octeți, cel mult 104857600 (limita de încărcare); o dimensiune mai mare răspunde cu 413 file_too_large.

Exemplu: 248000
folder_id
integer | null>= 1

Folderul din interiorul dosarului: un id de folder din documents.folders (acesta listează și folderele goale). Omiteți pentru rădăcina dosarului.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
upload_url
string

URL semnat. Trimiteți octeții fișierului aici prin PUT, cu tipul de conținut indicat ȘI antetul if_generation_match de mai jos: o cerere HTTPS obișnuită făcută de propriul dumneavoastră client HTTP (niciun instrument API sau MCP nu o trimite).

upload_token
string

Transmiteți aceasta către documents.upload.complete după ce operația PUT reușește.

content_type
string

Trimiteți exact acest Content-Type la operația PUT.

if_generation_match
string

Trimiteți această valoare ca antet "x-goog-if-generation-match" la operația PUT (întotdeauna "0"). Face încărcarea de unică folosință: operația PUT este acceptată doar cât timp obiectul nu există încă, astfel încât URL-ul semnat nu poate suprascrie un document deja arhivat.

object_key
string

Numele intern de stocare (pentru referință).

expires_in
integer

Secunde până la expirarea URL-ului de încărcare și a tokenului.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

413

Corpul cererii este prea mare (request_too_large) sau fișierul depășește limita de încărcare (file_too_large; details.max indică limita în octeți).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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
}'

Exemple de răspuns

{
  "data": {
    "upload_url": "string",
    "upload_token": "string",
    "content_type": "string",
    "if_generation_match": "string",
    "object_key": "string",
    "expires_in": 0
  }
}

Finalizați încărcarea unui document

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

Finalizează încărcarea unui document: după ce octeții au fost trimiși prin PUT către upload_url, înregistrează fișierul pe dosar ca o versiune nouă. Transmiteți upload_token de la documents.upload.init. Metadatele fișierului sunt preluate din token, nu din această cerere. Un folder șters între timp arhivează documentul la rădăcină.

Domeniu
documents:create
Permisiune Flowyer
cases:create

Parametri de cale

idobligatoriu
integer>= 1

Dosarul căruia îi aparține documentul (același ca la init).

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

upload_tokenobligatoriu
stringcel puțin 1 caracterecel mult 4096 caractere

Tokenul returnat de documents.upload.init.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
name
string

Numele fișierului așa cum este afișat în Flowyer: numele stocat împreună cu documentul sau numele de stocare al acestuia atunci când a fost importat dintr-un sistem mai vechi fără nume. documents.list este ordonat după numele stocat: documentele care au unul apar primele, în ordine alfabetică, apoi cele importate fără nume stocat, cele mai vechi primele (ordinea în care au fost arhivate în Flowyer), care, prin urmare, nu sunt sortate după numele afișat aici. Ordinea este aceeași pe fiecare pagină, astfel încât limit și offset parcurg lista fără repetări sau lacune.

Exemplu: "Contract_v2.docx"
size
integer | null

Octeți.

version
integer

Numărul versiunii curente a fișierului.

folder
object | null

Folderul în care este arhivat documentul sau null la rădăcina dosarului. documents.upload.complete răspunde cu null atunci când folderul ales la documents.upload.init a fost șters în timp ce octeții se încărcau: documentul este atunci arhivat la rădăcina dosarului, unde îl afișează Flowyer. Dacă rădăcina conține deja un document cu acel nume, încărcarea este arhivată sub un nume cu sufix ("Contract_2.pdf") în loc să devină o versiune nouă a acelui document fără legătură; răspunsul 201 reia name stocat.

Câmpurile folder
id
integer
name
string
path
string

Calea folderului în interiorul dosarului, separată prin "/".

folder_deleted
boolean

True atunci când documentul este arhivat într-un folder care nu mai există, lucru pe care lista de fișiere proprie a Flowyer nu îl afișează (folder este null pentru el, la fel ca pentru un document aflat la rădăcina dosarului). documents.upload.complete răspunde cu true doar dacă folderul a fost șters în timp ce octeții se încărcau ȘI mutarea fișierului stocat la rădăcina dosarului a eșuat: documentul este atunci păstrat în folderul șters, unde conținutul lui este încă accesibil. False pentru orice altceva, inclusiv o arhivare normală la rădăcină.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou. Este, de asemenea, răspunsul atunci când acest upload_token a fost deja finalizat.

dataobligatoriu
object
Câmpurile data
id
integer
name
string

Numele fișierului așa cum este afișat în Flowyer: numele stocat împreună cu documentul sau numele de stocare al acestuia atunci când a fost importat dintr-un sistem mai vechi fără nume. documents.list este ordonat după numele stocat: documentele care au unul apar primele, în ordine alfabetică, apoi cele importate fără nume stocat, cele mai vechi primele (ordinea în care au fost arhivate în Flowyer), care, prin urmare, nu sunt sortate după numele afișat aici. Ordinea este aceeași pe fiecare pagină, astfel încât limit și offset parcurg lista fără repetări sau lacune.

Exemplu: "Contract_v2.docx"
size
integer | null

Octeți.

version
integer

Numărul versiunii curente a fișierului.

folder
object | null

Folderul în care este arhivat documentul sau null la rădăcina dosarului. documents.upload.complete răspunde cu null atunci când folderul ales la documents.upload.init a fost șters în timp ce octeții se încărcau: documentul este atunci arhivat la rădăcina dosarului, unde îl afișează Flowyer. Dacă rădăcina conține deja un document cu acel nume, încărcarea este arhivată sub un nume cu sufix ("Contract_2.pdf") în loc să devină o versiune nouă a acelui document fără legătură; răspunsul 201 reia name stocat.

Câmpurile folder
id
integer
name
string
path
string

Calea folderului în interiorul dosarului, separată prin "/".

folder_deleted
boolean

True atunci când documentul este arhivat într-un folder care nu mai există, lucru pe care lista de fișiere proprie a Flowyer nu îl afișează (folder este null pentru el, la fel ca pentru un document aflat la rădăcina dosarului). documents.upload.complete răspunde cu true doar dacă folderul a fost șters în timp ce octeții se încărcau ȘI mutarea fișierului stocat la rădăcina dosarului a eșuat: documentul este atunci păstrat în folderul șters, unde conținutul lui este încă accesibil. False pentru orice altceva, inclusiv o arhivare normală la rădăcină.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. upload_not_finished: fișierul nu a ajuns încă în stocare; finalizați operația PUT către upload_url, apoi apelați complete din nou. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large) sau fișierul depășește limita de încărcare (file_too_large; details.max indică limita în octeți).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Descărcare document

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

Returnează un URL semnat cu durată scurtă de viață pentru a descărca un document după id, dacă dosarul său este vizibil. Efectuați GET pe url pentru a prelua octeții; expiră în câteva minute.

Domeniu
documents:download
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul documentului (din documents.list).

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
download_url
string

URL semnat. Efectuați GET pe el pentru a descărca octeții fișierului.

filename
string

Numele de fișier pentru descărcare.

size
integer | null

Octeți.

expires_in
integer

Numărul de secunde până la expirarea URL-ului.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/documents/1234/download' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "data": {
    "download_url": "string",
    "filename": "string",
    "size": 0,
    "expires_in": 0
  }
}

Redenumire document

PATCH /api/agent/documents/{id}

Redenumește un document (doar numele afișat; conținutul fișierului rămâne neschimbat). Noul nume trebuie să fie unic în aceeași mapă a dosarului. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409.

Domeniu
documents:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

nameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Noul nume de fișier, cel mult 255 de caractere INCLUSIV extensia. Extensia curentă este păstrată dacă nu furnizați una și contează la cele 255 (astfel, un nume fără extensie pentru "Beadvany.pdf" poate avea cel mult 251 de caractere). Text simplu; "<" și ">" nu sunt permise, deci un document al cărui nume stocat conține unul dintre ele poate fi redenumit doar în Flowyer.

Model: ^[^<>]*$
Exemplu: "Contract_signed.pdf"

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
name
string

Numele fișierului așa cum este afișat în Flowyer: numele stocat împreună cu documentul sau numele de stocare al acestuia atunci când a fost importat dintr-un sistem mai vechi fără nume. documents.list este ordonat după numele stocat: documentele care au unul apar primele, în ordine alfabetică, apoi cele importate fără nume stocat, cele mai vechi primele (ordinea în care au fost arhivate în Flowyer), care, prin urmare, nu sunt sortate după numele afișat aici. Ordinea este aceeași pe fiecare pagină, astfel încât limit și offset parcurg lista fără repetări sau lacune.

Exemplu: "Contract_v2.docx"
size
integer | null

Octeți.

version
integer

Numărul versiunii curente a fișierului.

folder
object | null

Folderul în care este arhivat documentul sau null la rădăcina dosarului. documents.upload.complete răspunde cu null atunci când folderul ales la documents.upload.init a fost șters în timp ce octeții se încărcau: documentul este atunci arhivat la rădăcina dosarului, unde îl afișează Flowyer. Dacă rădăcina conține deja un document cu acel nume, încărcarea este arhivată sub un nume cu sufix ("Contract_2.pdf") în loc să devină o versiune nouă a acelui document fără legătură; răspunsul 201 reia name stocat.

Câmpurile folder
id
integer
name
string
path
string

Calea folderului în interiorul dosarului, separată prin "/".

folder_deleted
boolean

True atunci când documentul este arhivat într-un folder care nu mai există, lucru pe care lista de fișiere proprie a Flowyer nu îl afișează (folder este null pentru el, la fel ca pentru un document aflat la rădăcina dosarului). documents.upload.complete răspunde cu true doar dacă folderul a fost șters în timp ce octeții se încărcau ȘI mutarea fișierului stocat la rădăcina dosarului a eșuat: documentul este atunci păstrat în folderul șters, unde conținutul lui este încă accesibil. False pentru orice altceva, inclusiv o arhivare normală la rădăcină.

created_by_user_id
integer | null
created_by
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a modificat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at), sau un alt document din aceeași mapă are deja acest nume (duplicate_name; alegeți alt nume, nu reîncercați cu același).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Redenumire folder de dosar

PATCH /api/agent/folders/{id}

Redenumește un folder (doar numele lui; fișierele și subfolderele lui își păstrează locul). Numele este text simplu ("<" și ">" nu sunt permise). Transmiteți expected_updated_at din ultima citire (documents.folders îl listează); o modificare conflictuală răspunde cu 409.

Domeniu
documents:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

nameobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Noul nume al folderului, cel mult 255 de caractere. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Beadványok"

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul folderului: transmiteți-l ca folder_id către documents.upload.init, sau ca parent_id către documents.folders.create.

name
string

Numele folderului așa cum este afișat în Flowyer.

parent_id
integer | null

Id-ul folderului părinte; null pentru un folder aflat la rădăcina dosarului.

path
string

Calea folderului în interiorul dosarului, separată prin "/", de exemplu "/Iratok/Beadványok".

updated_at
string <date-time> | null

Transmiteți aceasta către documents.folders.rename ca expected_updated_at.

updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "data": {
    "id": 1234,
    "name": "string",
    "parent_id": 1234,
    "path": "string",
    "updated_at": "2026-10-30T09:15:00+01:00"
  },
  "updated": true
}

Bază de cunoștințe

Listare articole din baza de cunoștințe

GET /api/agent/knowledge/articles

Listează articolele din baza de cunoștințe pe care utilizatorul le poate vedea (cele proprii ale autorului, articolele globale și articolele partajate cu rolul utilizatorului). Toate statusurile în mod implicit; filtrați după status sau transmiteți q pentru a căuta full-text în titluri, rezumate, conținut și etichete.

Domeniu
knowledge:read

Parametri de interogare

q
string | nullcel mult 255 caractere

Termen de căutare full-text (titluri, rezumate, conținut și nume de etichete). Operatorii booleeni sunt eliminați.

Exemplu: "felmondási idő"
status
string | null

Doar articolele cu acest status. Omiteți pentru a lista fiecare status.

Valori permise: "draft" "published" "archived"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 9876
slug
string

Slug de URL generat de server.

Exemplu: "felmondasi-ido"
title
string
Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML îmbogățit, așa cum este stocat).

content
string

Corpul articolului așa cum este stocat (HTML îmbogățit).

status
string
Valori permise: "draft" "published" "archived"
is_featured
boolean

Dacă articolul este fixat pe pagina principală a bazei de cunoștințe (nu poate fi setat prin API).

category_id
integer | null
category_name
string | null
author_id
integer

Id-ul de utilizator al autorului; 0 pentru un articol global (implicit).

author_name
string | null
editor_id
integer | null

Id-ul de utilizator al ultimului editor, sau null dacă nu a fost editat niciodată.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id-urile de rol cu care este partajat articolul (gol = doar autorul/global).

tags
string[]

Numele etichetelor de pe articol.

published_at
string <date-time> | null

Când a fost publicat prima dată articolul, sau null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/knowledge/articles?q=felmond%C3%A1si%20id%C5%91&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere articol din baza de cunoștințe

GET /api/agent/knowledge/articles/{id}

Returnează un articol din baza de cunoștințe, inclusiv conținutul complet, etichetele și rolurile partajate. Răspunde cu 404 când articolul nu există sau utilizatorul nu îl poate vedea.

Domeniu
knowledge:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul articolului.

Exemplu: 9876

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
slug
string

Slug de URL generat de server.

Exemplu: "felmondasi-ido"
title
string
Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML îmbogățit, așa cum este stocat).

content
string

Corpul articolului așa cum este stocat (HTML îmbogățit).

status
string
Valori permise: "draft" "published" "archived"
is_featured
boolean

Dacă articolul este fixat pe pagina principală a bazei de cunoștințe (nu poate fi setat prin API).

category_id
integer | null
category_name
string | null
author_id
integer

Id-ul de utilizator al autorului; 0 pentru un articol global (implicit).

author_name
string | null
editor_id
integer | null

Id-ul de utilizator al ultimului editor, sau null dacă nu a fost editat niciodată.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id-urile de rol cu care este partajat articolul (gol = doar autorul/global).

tags
string[]

Numele etichetelor de pe articol.

published_at
string <date-time> | null

Când a fost publicat prima dată articolul, sau null.

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/knowledge/articles/9876' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
  }
}

Creare articol în baza de cunoștințe

POST /api/agent/knowledge/articles

Creează un articol în baza de cunoștințe, având ca autor utilizatorul cheii. Slug-ul este generat din titlu. Categoria trebuie să existe și să fie activă. Partajați-l cu roluri prin shared_roles (altfel îl vede doar autorul). content și excerpt sunt HTML și sunt igienizate pe partea de server.

Domeniu
knowledge:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

titleobligatoriu
stringcel mult 500 caractere

Titlul articolului. Text simplu.

Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML permis, igienizat pe partea de server), cel mult 200 de caractere.

contentobligatoriu
string

Corpul articolului. HTML îmbogățit, igienizat pe partea de server cu profilul bazei de cunoștințe.

category_idobligatoriu
integer>= 1

Id-ul unei categorii existente și active din baza de cunoștințe.

Exemplu: 12
statusobligatoriu
string

draft, published sau archived. published marchează published_at.

Valori permise: "draft" "published" "archived"
tags
string[] | null

Nume de etichete; etichetele noi sunt create după necesitate.

shared_roles
integer[] | null

Id-urile de rol cu care se partajează articolul. Gol înseamnă că doar autorul îl poate vedea.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
slug
string

Slug de URL generat de server.

Exemplu: "felmondasi-ido"
title
string
Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML îmbogățit, așa cum este stocat).

content
string

Corpul articolului așa cum este stocat (HTML îmbogățit).

status
string
Valori permise: "draft" "published" "archived"
is_featured
boolean

Dacă articolul este fixat pe pagina principală a bazei de cunoștințe (nu poate fi setat prin API).

category_id
integer | null
category_name
string | null
author_id
integer

Id-ul de utilizator al autorului; 0 pentru un articol global (implicit).

author_name
string | null
editor_id
integer | null

Id-ul de utilizator al ultimului editor, sau null dacă nu a fost editat niciodată.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id-urile de rol cu care este partajat articolul (gol = doar autorul/global).

tags
string[]

Numele etichetelor de pe articol.

published_at
string <date-time> | null

Când a fost publicat prima dată articolul, sau null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
slug
string

Slug de URL generat de server.

Exemplu: "felmondasi-ido"
title
string
Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML îmbogățit, așa cum este stocat).

content
string

Corpul articolului așa cum este stocat (HTML îmbogățit).

status
string
Valori permise: "draft" "published" "archived"
is_featured
boolean

Dacă articolul este fixat pe pagina principală a bazei de cunoștințe (nu poate fi setat prin API).

category_id
integer | null
category_name
string | null
author_id
integer

Id-ul de utilizator al autorului; 0 pentru un articol global (implicit).

author_name
string | null
editor_id
integer | null

Id-ul de utilizator al ultimului editor, sau null dacă nu a fost editat niciodată.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id-urile de rol cu care este partajat articolul (gol = doar autorul/global).

tags
string[]

Numele etichetelor de pe articol.

published_at
string <date-time> | null

Când a fost publicat prima dată articolul, sau null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare articol din baza de cunoștințe

PATCH /api/agent/knowledge/articles/{id}

Modifică un articol din baza de cunoștințe: titlul (slug-ul este re-derivat), rezumatul, conținutul, categoria, statusul, etichetele sau rolurile partajate. Doar autorul (sau oricine, pentru un articol global) poate edita. Transmiteți expected_updated_at; o modificare conflictuală răspunde cu 409. content și excerpt sunt igienizate pe partea de server.

Domeniu
knowledge:update

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

title
string | null

Titlul articolului (text simplu). null păstrează titlul curent; un titlu nou re-derivă slug-ul.

excerpt
string | null

Rezumat scurt (HTML permis, igienizat), cel mult 200 de caractere ca valoare NOUĂ. Gol/null îl șterge; omiteți pentru a-l păstra.

content
string | null

Corpul articolului (HTML îmbogățit, igienizat). null păstrează conținutul curent; nu poate fi șters.

category_id
integer | null>= 1

Mută articolul în această categorie existentă și activă. null o păstrează pe cea curentă.

status
string | null

draft, published sau archived. Prima trecere la published marchează published_at; acesta nu este șters niciodată. null păstrează statusul curent.

Valori permise: "draft" "published" "archived"
tags
string[] | null

Înlocuiește întregul set de etichete (etichetele noi sunt create). Un array gol șterge toate etichetele; omiteți pentru a le păstra.

shared_roles
integer[] | null

Înlocuiește întregul set de roluri partajate. Un array gol elimină toată partajarea (doar autorul îl vede); omiteți pentru a-l păstra.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
slug
string

Slug de URL generat de server.

Exemplu: "felmondasi-ido"
title
string
Exemplu: "Felmondási idő a munka törvénykönyvében"
excerpt
string | null

Rezumat scurt (HTML îmbogățit, așa cum este stocat).

content
string

Corpul articolului așa cum este stocat (HTML îmbogățit).

status
string
Valori permise: "draft" "published" "archived"
is_featured
boolean

Dacă articolul este fixat pe pagina principală a bazei de cunoștințe (nu poate fi setat prin API).

category_id
integer | null
category_name
string | null
author_id
integer

Id-ul de utilizator al autorului; 0 pentru un articol global (implicit).

author_name
string | null
editor_id
integer | null

Id-ul de utilizator al ultimului editor, sau null dacă nu a fost editat niciodată.

editor_name
string | null
views_count
integer
downloads_count
integer
shared_roles
integer[]

Id-urile de rol cu care este partajat articolul (gol = doar autorul/global).

tags
string[]

Numele etichetelor de pe articol.

published_at
string <date-time> | null

Când a fost publicat prima dată articolul, sau null.

created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Listare categorii din baza de cunoștințe

GET /api/agent/knowledge/categories

Listează categoriile din baza de cunoștințe pe care utilizatorul le poate vedea: categoriile implicite încorporate, cele proprii ale utilizatorului și cele partajate cu rolul utilizatorului. Ordonate ca în Flowyer (poziția de sortare, apoi numele).

Domeniu
knowledge:read

Parametri de interogare

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 42
slug
string

Slug de URL, generat din nume.

Exemplu: "munkajog"
name
string
Exemplu: "Munkajog"
description
string | null

Descriere în text simplu, sau null.

icon
string | null

Identificatorul pictogramei afișate lângă categorie, sau null.

order_column
integer

Poziția de sortare între categoriile de același nivel.

Exemplu: 0
is_active
boolean
parent_id
integer | null

Id-ul categoriei părinte, sau null pentru o categorie rădăcină.

author_id
integer

Id-ul de utilizator al creatorului; 0 pentru o categorie implicită încorporată, vizibilă tuturor.

author_name
string | null

Numele afișat al creatorului, sau null pentru o categorie implicită.

articles_count
integer

Numărul de articole publicate din această categorie pe care apelantul le poate vedea.

shared_roles
integer[]

Id-urile de rol cu care este partajată această categorie. Gol înseamnă că doar autorul o vede (o categorie implicită cu author_id 0 este vizibilă tuturor).

created_at
string <date-time> | null
updated_at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/knowledge/categories?limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere categorie din baza de cunoștințe

GET /api/agent/knowledge/categories/{id}

Returnează o categorie din baza de cunoștințe. Răspunde cu 404 când categoria nu există sau nu este vizibilă pentru utilizatorul care deține această cheie API.

Domeniu
knowledge:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul categoriei.

Exemplu: 42

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 42
slug
string

Slug de URL, generat din nume.

Exemplu: "munkajog"
name
string
Exemplu: "Munkajog"
description
string | null

Descriere în text simplu, sau null.

icon
string | null

Identificatorul pictogramei afișate lângă categorie, sau null.

order_column
integer

Poziția de sortare între categoriile de același nivel.

Exemplu: 0
is_active
boolean
parent_id
integer | null

Id-ul categoriei părinte, sau null pentru o categorie rădăcină.

author_id
integer

Id-ul de utilizator al creatorului; 0 pentru o categorie implicită încorporată, vizibilă tuturor.

author_name
string | null

Numele afișat al creatorului, sau null pentru o categorie implicită.

articles_count
integer

Numărul de articole publicate din această categorie pe care apelantul le poate vedea.

shared_roles
integer[]

Id-urile de rol cu care este partajată această categorie. Gol înseamnă că doar autorul o vede (o categorie implicită cu author_id 0 este vizibilă tuturor).

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/knowledge/categories/42' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
  }
}

Creare categorie în baza de cunoștințe

POST /api/agent/knowledge/categories

Creează o categorie în baza de cunoștințe. Slug-ul de URL este generat din nume. Partajați-o cu roluri prin shared_roles sau omiteți-le astfel încât doar dumneavoastră (autorul) să o puteți vedea. Un parent_id, când este furnizat, trebuie să fie o categorie existentă și activă.

Domeniu
knowledge:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

nameobligatoriu
stringcel mult 255 caractere

Numele categoriei. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Munkajog"
description
string | null

Descriere opțională, text simplu.

parent_id
integer | null>= 1

Id-ul categoriei părinte (trebuie să existe și să fie activă). Omiteți pentru o categorie rădăcină.

icon
string | nullcel mult 100 caractere

Identificator de pictogramă opțional. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
is_active
boolean | null

Dacă categoria este activă. Implicit true.

Implicit: true
order_column
integer | null>= 0

Poziția de sortare între categoriile de același nivel. Implicit 0.

Exemplu: 0
shared_roles
integer[] | null

Id-urile de rol cu care se partajează această categorie. Omiteți astfel încât doar dumneavoastră (autorul) să o puteți vedea.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 42
slug
string

Slug de URL, generat din nume.

Exemplu: "munkajog"
name
string
Exemplu: "Munkajog"
description
string | null

Descriere în text simplu, sau null.

icon
string | null

Identificatorul pictogramei afișate lângă categorie, sau null.

order_column
integer

Poziția de sortare între categoriile de același nivel.

Exemplu: 0
is_active
boolean
parent_id
integer | null

Id-ul categoriei părinte, sau null pentru o categorie rădăcină.

author_id
integer

Id-ul de utilizator al creatorului; 0 pentru o categorie implicită încorporată, vizibilă tuturor.

author_name
string | null

Numele afișat al creatorului, sau null pentru o categorie implicită.

articles_count
integer

Numărul de articole publicate din această categorie pe care apelantul le poate vedea.

shared_roles
integer[]

Id-urile de rol cu care este partajată această categorie. Gol înseamnă că doar autorul o vede (o categorie implicită cu author_id 0 este vizibilă tuturor).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 42
slug
string

Slug de URL, generat din nume.

Exemplu: "munkajog"
name
string
Exemplu: "Munkajog"
description
string | null

Descriere în text simplu, sau null.

icon
string | null

Identificatorul pictogramei afișate lângă categorie, sau null.

order_column
integer

Poziția de sortare între categoriile de același nivel.

Exemplu: 0
is_active
boolean
parent_id
integer | null

Id-ul categoriei părinte, sau null pentru o categorie rădăcină.

author_id
integer

Id-ul de utilizator al creatorului; 0 pentru o categorie implicită încorporată, vizibilă tuturor.

author_name
string | null

Numele afișat al creatorului, sau null pentru o categorie implicită.

articles_count
integer

Numărul de articole publicate din această categorie pe care apelantul le poate vedea.

shared_roles
integer[]

Id-urile de rol cu care este partajată această categorie. Gol înseamnă că doar autorul o vede (o categorie implicită cu author_id 0 este vizibilă tuturor).

created_at
string <date-time> | null
updated_at
string <date-time> | null
created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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
}'

Exemple de răspuns

{
  "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
}

Actualizare categorie din baza de cunoștințe

PATCH /api/agent/knowledge/categories/{id}

Modifică o categorie din baza de cunoștințe: numele (slug-ul îl urmează), descrierea, pictograma, părintele, indicatorul activ, poziția de sortare sau rolurile cu care este partajată. Doar autorul o poate modifica (o categorie implicită încorporată poate fi editată de oricine). Transmiteți expected_updated_at; o modificare conflictuală răspunde cu 409.

Domeniu
knowledge:update

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

name
string | nullcel puțin 1 caractere

Numele categoriei. Cel mult 255 de caractere ca valoare NOUĂ; "<" și ">" nu pot fi introduse, dar un nume stocat care este mai lung sau le conține poate fi trimis înapoi nemodificat. null păstrează numele curent.

description
string | null

Descriere în text simplu. null o șterge.

parent_id
integer | null>= 1

Mută categoria sub acest părinte (trebuie să existe, să fie activ și să nu creeze un ciclu), sau null pentru a o face o categorie rădăcină.

icon
string | null

Identificator de pictogramă. Cel mult 100 de caractere ca valoare NOUĂ; "<" și ">" nu pot fi introduse. null îl șterge.

is_active
boolean | null

Indicator activ. Omiteți sau null pentru a păstra valoarea curentă.

order_column
integer | null>= 0

Poziția de sortare între categoriile de același nivel. Omiteți sau null pentru a păstra valoarea curentă.

shared_roles
integer[] | null

Înlocuiește setul de id-uri de rol cu care este partajată această categorie. Un array gol elimină toată partajarea (doar autorul o vede). Omiteți pentru a lăsa partajarea neschimbată.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 42
slug
string

Slug de URL, generat din nume.

Exemplu: "munkajog"
name
string
Exemplu: "Munkajog"
description
string | null

Descriere în text simplu, sau null.

icon
string | null

Identificatorul pictogramei afișate lângă categorie, sau null.

order_column
integer

Poziția de sortare între categoriile de același nivel.

Exemplu: 0
is_active
boolean
parent_id
integer | null

Id-ul categoriei părinte, sau null pentru o categorie rădăcină.

author_id
integer

Id-ul de utilizator al creatorului; 0 pentru o categorie implicită încorporată, vizibilă tuturor.

author_name
string | null

Numele afișat al creatorului, sau null pentru o categorie implicită.

articles_count
integer

Numărul de articole publicate din această categorie pe care apelantul le poate vedea.

shared_roles
integer[]

Id-urile de rol cu care este partajată această categorie. Gol înseamnă că doar autorul o vede (o categorie implicită cu author_id 0 este vizibilă tuturor).

created_at
string <date-time> | null
updated_at
string <date-time> | null
updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

E-mailuri

Listare e-mailuri de dosar

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

Listează e-mailurile salvate pe un dosar: numele și adresa expeditorului, subiectul, dimensiunea și colegul care a salvat fiecare, cele mai nou trimise primele. Doar antet și metadate, niciodată corpul sau HTML-ul brut. Folosiți emails.get pentru corpul în text simplu al unui singur mesaj.

Domeniu
emails:read
Permisiune Flowyer
emails:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

q
stringcel mult 100 caractere

Filtrați după subiect, numele expeditorului sau adresa expeditorului (fără sensibilitate la diacritice și majuscule/minuscule). Nu după corp.

Exemplu: "invoice"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul e-mailului (folosiți cu emails.get).

Exemplu: 1234
from_name
string | null

Numele afișat al părții externe. Stocarea nu păstrează coloane de direcție sau de destinatar, așa că aceasta este întotdeauna partea externă, niciodată un coleg, iar API-ul nu poate spune dacă e-mailul a fost primit sau trimis.

from_address
string | null

Adresa SMTP a părții externe.

subject
string | null
sent_at
string <date-time> | null

Când a fost trimis mesajul. Fusul orar al valorii stocate este inconsecvent în funcție de calea de preluare (workerul IMAP stochează UTC, add-inul Outlook stochează o oră de perete în fusul biroului), așa că este pe cât posibil și ordinea listei după el poate fi decalată cu offsetul UTC al biroului între surse. created_at este marcajul temporal fiabil.

size
integer | null

Octeții fișierului .eml/.msg stocat.

extension
string | null

"msg" (add-in Outlook) sau "eml" (IMAP / implicit); null pe unele rânduri mai vechi.

saved_by_user_id
integer | null

Id-ul de utilizator al colegului care a salvat e-mailul în Flowyer.

saved_by
string | null

Numele afișat al acelui coleg.

created_at
string <date-time> | null

Când a fost salvat e-mailul în Flowyer (oră de perete în fusul biroului). Marcajul temporal fiabil pentru o paginare stabilă.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/matters/1234/emails?q=invoice&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere e-mail

GET /api/agent/emails/{id}

Returnează un e-mail salvat al unui dosar cu corpul său în text simplu (expeditor, subiect, dimensiune și cine l-a salvat). Corpul HTML brut nu este returnat niciodată. Răspunde cu 404 când e-mailul nu există sau dosarul său nu este vizibil pentru utilizatorul care deține această cheie API.

Domeniu
emails:read
Permisiune Flowyer
emails:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul e-mailului.

Exemplu: 1234

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 1234
matter
object | null

Dosarul sub care este arhivat e-mailul, sau null pentru un e-mail fără dosar (salvat în afara oricărui caz).

Câmpurile matter
id
integer
case_number
string
from_name
string | null

Numele afișat al părții externe (niciodată un coleg; stocarea nu are o coloană de direcție).

from_address
string | null

Adresa SMTP a părții externe.

subject
string | null
body
string | null

Corpul mesajului în text simplu. Corpul HTML brut nu este returnat niciodată în mod deliberat (HTML terț, de încredere scăzută). Text simplu, pe cât posibil: dacă HTML-ul original conținea <style>/<script>, textul lor interior poate supraviețui în el.

sent_at
string <date-time> | null

Când a fost trimis mesajul. Fusul orar este inconsecvent în funcție de calea de preluare (IMAP stochează UTC, add-inul Outlook o oră de perete în fusul biroului); created_at este marcajul temporal fiabil.

size
integer | null

Octeții fișierului .eml/.msg stocat.

extension
string | null

"msg" sau "eml"; null pe unele rânduri mai vechi.

saved_by_user_id
integer | null

Id-ul de utilizator al colegului care a salvat e-mailul în Flowyer.

saved_by
string | null

Numele afișat al acelui coleg.

created_at
string <date-time> | null

Când a fost salvat e-mailul în Flowyer (oră de perete în fusul biroului).

updated_at
string <date-time> | null
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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"
  }
}

Istoric litigiu

Listare istoric litigiu al dosarului

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

Listează intrările din istoricul litigiului (pertörténet) ale unui dosar, cel mai nou eveniment primul: o notă datată cu un titlu, o descriere HTML și o locație. Răspunde cu 404 când dosarul nu este vizibil pentru utilizator.

Domeniu
litigation:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 4521
title
string

Titlul intrării. Text simplu.

Exemplu: "Első tárgyalás elhalasztva"
description
string | null

Detaliile intrării ca HTML îmbogățit, igienizat pe partea de server.

location
string | null

Unde a avut loc (text simplu), de exemplu o sală de judecată; poate fi null.

event_date
string <date> | null

Ziua intrării, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

user_id
integer | null

Autorul (utilizatorul care a creat intrarea).

created_by
string | null

Numele afișat al autorului.

last_editor_id
integer | null

Utilizatorul care a editat ultima dată intrarea.

last_editor
string | null

Numele afișat al ultimului editor.

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

Transmiteți aceasta către litigation.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Creare intrare în istoricul litigiului

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

Adaugă o intrare în istoricul litigiului (pertörténet) la un dosar: un titlu (text simplu, "<"/">" nu sunt permise), o descriere HTML opțională (igienizată pe partea de server), o locație opțională și o dată a evenimentului (implicit astăzi). Răspunde cu 404 când dosarul nu este vizibil.

Domeniu
litigation:create
Permisiune Flowyer
cases:create

Parametri de cale

idobligatoriu
integer>= 1

Dosarul de care aparține intrarea (trebuie să fie vizibil).

Exemplu: 1234

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

titleobligatoriu
stringcel puțin 1 caracterecel mult 2000 caractere

Titlul intrării, cel mult 2000 de caractere. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Első tárgyalás elhalasztva"
description
string | null

Detaliile intrării. HTML îmbogățit, igienizat pe partea de server cu profilul bazei de cunoștințe.

location
string | nullcel mult 255 caractere

Unde a avut loc (text simplu, cel mult 255 de caractere); "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Fővárosi Törvényszék, 215. tárgyaló"
event_date
string <date> | null

Ziua intrării, YYYY-MM-DD. Implicit astăzi (fusul orar al biroului).

Exemplu: "2026-11-15"
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4521
title
string

Titlul intrării. Text simplu.

Exemplu: "Első tárgyalás elhalasztva"
description
string | null

Detaliile intrării ca HTML îmbogățit, igienizat pe partea de server.

location
string | null

Unde a avut loc (text simplu), de exemplu o sală de judecată; poate fi null.

event_date
string <date> | null

Ziua intrării, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

user_id
integer | null

Autorul (utilizatorul care a creat intrarea).

created_by
string | null

Numele afișat al autorului.

last_editor_id
integer | null

Utilizatorul care a editat ultima dată intrarea.

last_editor
string | null

Numele afișat al ultimului editor.

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

Transmiteți aceasta către litigation.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4521
title
string

Titlul intrării. Text simplu.

Exemplu: "Első tárgyalás elhalasztva"
description
string | null

Detaliile intrării ca HTML îmbogățit, igienizat pe partea de server.

location
string | null

Unde a avut loc (text simplu), de exemplu o sală de judecată; poate fi null.

event_date
string <date> | null

Ziua intrării, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

user_id
integer | null

Autorul (utilizatorul care a creat intrarea).

created_by
string | null

Numele afișat al autorului.

last_editor_id
integer | null

Utilizatorul care a editat ultima dată intrarea.

last_editor
string | null

Numele afișat al ultimului editor.

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

Transmiteți aceasta către litigation.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare intrare din istoricul litigiului

PATCH /api/agent/litigation/{id}

Modifică o intrare din istoricul litigiului (pertörténet): titlul, descrierea, locația sau data evenimentului. Se scriu doar câmpurile pe care le trimiteți; descrierea este igienizată pe partea de server. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409.

Domeniu
litigation:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

title
string | nullcel puțin 1 caracterecel mult 2000 caractere

Titlu nou, cel mult 2000 de caractere (text simplu; "<"/">" nu sunt permise). Omiteți pentru a-l păstra pe cel curent.

Model: ^[^<>]*$
Exemplu: "Ítélethirdetés elhalasztva"
description
string | null

Detalii noi (HTML îmbogățit, igienizat). Omiteți pentru a le păstra pe cele curente; null/gol le șterge.

location
string | nullcel mult 255 caractere

Locație nouă (text simplu, cel mult 255 de caractere; "<"/">" nu sunt permise). Omiteți pentru a o păstra; null/gol o șterge.

Model: ^[^<>]*$
event_date
string <date> | null

Noua zi a evenimentului, YYYY-MM-DD. Omiteți pentru a o păstra; null o șterge.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4521
title
string

Titlul intrării. Text simplu.

Exemplu: "Első tárgyalás elhalasztva"
description
string | null

Detaliile intrării ca HTML îmbogățit, igienizat pe partea de server.

location
string | null

Unde a avut loc (text simplu), de exemplu o sală de judecată; poate fi null.

event_date
string <date> | null

Ziua intrării, YYYY-MM-DD. Flowyer înregistrează doar data, fără ora din zi.

user_id
integer | null

Autorul (utilizatorul care a creat intrarea).

created_by
string | null

Numele afișat al autorului.

last_editor_id
integer | null

Utilizatorul care a editat ultima dată intrarea.

last_editor
string | null

Numele afișat al ultimului editor.

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

Transmiteți aceasta către litigation.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Registru de corespondență

Listare registru de corespondență

GET /api/agent/mail-register

Listează intrările din registrul de corespondență (Postakönyv) arhivate pe dosarele pe care utilizatorul le poate vedea, cele mai noi primele. Filtrați după dosar, direcție, text liber (subiect/expeditor/destinatar/număr de urmărire) și interval de date. Corespondența dosarelor arhivate este ascunsă, cu excepția cazului în care include_archived este true.

Domeniu
mail_register:read
Permisiune Flowyer
mail:read

Parametri de interogare

matter_id
integer>= 1

Doar intrările acestui dosar (trebuie să fie vizibil pentru utilizator).

Exemplu: 1234
direction
string

Doar intrările incoming (primite) sau outgoing (trimise).

Valori permise: "incoming" "outgoing"
q
stringcel mult 100 caractere

Căutare text liber în subiect, expeditor, destinatar, recipient și numărul de urmărire (ignorând majusculele/minusculele).

Exemplu: "Kúria"
date_from
string <date>

Doar intrările a căror dată este în această zi sau ulterioară (YYYY-MM-DD).

Exemplu: "2026-01-01"
date_to
string <date>

Doar intrările a căror dată este în această zi sau anterioară (YYYY-MM-DD).

Exemplu: "2026-12-31"
updated_since
string <date-time>

Doar intrările modificate la acest moment sau după el (ISO 8601).

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

Include intrările dosarelor arhivate.

Implicit: false
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul intrării din registrul de corespondență (folosiți cu mail_register.get / .update).

Exemplu: 4321
matter
object | null

Dosarul pe care este arhivată intrarea.

Câmpurile matter
id
integer
case_number
string
direction
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

subject
string | null
sender
string | null

Feladó: expeditorul (text liber).

to
string | null

Címzett: destinatarul (text liber).

recipient
string | null

Pentru o corespondență incoming: numele afișat al colegului care a primit-o. Pentru o corespondență outgoing: destinatarul/primitorul în text liber.

recipient_user_id
integer | null

Setat doar pentru o corespondență incoming al cărei destinatar este un coleg (un id de utilizator); null pentru o corespondență outgoing.

electronic
boolean

True când elementul a fost înregistrat ca electronic (type_of_mail).

delivery_method_id
integer | null

Id-ul metodei de livrare (mail_delivery_methods).

delivery_method
string | null

Eticheta localizată a metodei de livrare (Posta, Cégkapu, Perkapu, ...), sau varianta de rezervă electronic/neelectronic pentru un rând mai vechi.

tracking_no
string | null

Azonosító: numărul de urmărire.

folder_path
string | null
recorded_by_user_id
integer | null

Colegul care a înregistrat intrarea.

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

Transmiteți aceasta către mail_register.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/mail-register?matter_id=1234&q=K%C3%BAria&date_from=2026-01-01' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere intrare din registrul de corespondență

GET /api/agent/mail-register/{id}

Returnează o intrare din registrul de corespondență (Postakönyv) după id, cu updated_at al acesteia (tokenul pe care îl acceptă mail_register.update). Răspunde cu 404 când intrarea nu există sau dosarul său nu este vizibil pentru utilizator.

Domeniu
mail_register:read
Permisiune Flowyer
mail:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul intrării din registrul de corespondență.

Exemplu: 4321

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării din registrul de corespondență (folosiți cu mail_register.get / .update).

Exemplu: 4321
matter
object | null

Dosarul pe care este arhivată intrarea.

Câmpurile matter
id
integer
case_number
string
direction
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

subject
string | null
sender
string | null

Feladó: expeditorul (text liber).

to
string | null

Címzett: destinatarul (text liber).

recipient
string | null

Pentru o corespondență incoming: numele afișat al colegului care a primit-o. Pentru o corespondență outgoing: destinatarul/primitorul în text liber.

recipient_user_id
integer | null

Setat doar pentru o corespondență incoming al cărei destinatar este un coleg (un id de utilizator); null pentru o corespondență outgoing.

electronic
boolean

True când elementul a fost înregistrat ca electronic (type_of_mail).

delivery_method_id
integer | null

Id-ul metodei de livrare (mail_delivery_methods).

delivery_method
string | null

Eticheta localizată a metodei de livrare (Posta, Cégkapu, Perkapu, ...), sau varianta de rezervă electronic/neelectronic pentru un rând mai vechi.

tracking_no
string | null

Azonosító: numărul de urmărire.

folder_path
string | null
recorded_by_user_id
integer | null

Colegul care a înregistrat intrarea.

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

Transmiteți aceasta către mail_register.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/mail-register/4321' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
    }
  }
}

Creare intrare în registrul de corespondență

POST /api/agent/mail-register

Arhivează o nouă intrare în registrul de corespondență (Postakönyv) pe un dosar. Folosiți recipient_user_id pentru o corespondență incoming primită de un coleg, sau recipient (text liber) pentru una outgoing. delivery_method_id trebuie să fie o metodă cunoscută. Răspunde cu 404 când dosarul nu este vizibil.

Domeniu
mail_register:create
Permisiune Flowyer
mail:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

matter_idobligatoriu
integer>= 1

Dosarul de care aparține intrarea (trebuie să fie vizibil).

Exemplu: 1234
directionobligatoriu
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
dateobligatoriu
string <date>

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

Exemplu: "2026-11-03"
subjectobligatoriu
stringcel puțin 1 caracterecel mult 1000 caractere

Subiectul corespondenței. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Fellebbezés a Kúriához"
sender
string | nullcel mult 1000 caractere

Feladó: expeditorul (text liber). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
to
string | nullcel mult 1000 caractere

Címzett: destinatarul (text liber). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
recipient
string | nullcel mult 1000 caractere

Corespondență outgoing: destinatarul/primitorul în text liber. Nu este permis împreună cu recipient_user_id. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
recipient_user_id
integer | null>= 1

Corespondență incoming: colegul care a primit-o (un id de utilizator din colleagues.list), stocat ca recipient numeric. Nu este permis împreună cu recipient.

electronic
boolean

Dacă elementul este electronic (type_of_mail); independent de metoda de livrare. Implicit false.

Implicit: false
delivery_method_id
integer | null>= 1

Id-ul metodei de livrare (mail_delivery_methods): de exemplu 1 Posta, 4 Cégkapu, 7 Perkapu. 422 când este necunoscut.

tracking_no
string | nullcel mult 255 caractere

Azonosító: numărul de urmărire. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
folder_path
string | nullcel mult 1000 caractere
Model: ^[^<>]*$
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării din registrul de corespondență (folosiți cu mail_register.get / .update).

Exemplu: 4321
matter
object | null

Dosarul pe care este arhivată intrarea.

Câmpurile matter
id
integer
case_number
string
direction
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

subject
string | null
sender
string | null

Feladó: expeditorul (text liber).

to
string | null

Címzett: destinatarul (text liber).

recipient
string | null

Pentru o corespondență incoming: numele afișat al colegului care a primit-o. Pentru o corespondență outgoing: destinatarul/primitorul în text liber.

recipient_user_id
integer | null

Setat doar pentru o corespondență incoming al cărei destinatar este un coleg (un id de utilizator); null pentru o corespondență outgoing.

electronic
boolean

True când elementul a fost înregistrat ca electronic (type_of_mail).

delivery_method_id
integer | null

Id-ul metodei de livrare (mail_delivery_methods).

delivery_method
string | null

Eticheta localizată a metodei de livrare (Posta, Cégkapu, Perkapu, ...), sau varianta de rezervă electronic/neelectronic pentru un rând mai vechi.

tracking_no
string | null

Azonosító: numărul de urmărire.

folder_path
string | null
recorded_by_user_id
integer | null

Colegul care a înregistrat intrarea.

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

Transmiteți aceasta către mail_register.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării din registrul de corespondență (folosiți cu mail_register.get / .update).

Exemplu: 4321
matter
object | null

Dosarul pe care este arhivată intrarea.

Câmpurile matter
id
integer
case_number
string
direction
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

subject
string | null
sender
string | null

Feladó: expeditorul (text liber).

to
string | null

Címzett: destinatarul (text liber).

recipient
string | null

Pentru o corespondență incoming: numele afișat al colegului care a primit-o. Pentru o corespondență outgoing: destinatarul/primitorul în text liber.

recipient_user_id
integer | null

Setat doar pentru o corespondență incoming al cărei destinatar este un coleg (un id de utilizator); null pentru o corespondență outgoing.

electronic
boolean

True când elementul a fost înregistrat ca electronic (type_of_mail).

delivery_method_id
integer | null

Id-ul metodei de livrare (mail_delivery_methods).

delivery_method
string | null

Eticheta localizată a metodei de livrare (Posta, Cégkapu, Perkapu, ...), sau varianta de rezervă electronic/neelectronic pentru un rând mai vechi.

tracking_no
string | null

Azonosító: numărul de urmărire.

folder_path
string | null
recorded_by_user_id
integer | null

Colegul care a înregistrat intrarea.

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

Transmiteți aceasta către mail_register.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare intrare din registrul de corespondență

PATCH /api/agent/mail-register/{id}

Actualizează o intrare din registrul de corespondență (Postakönyv); se modifică doar câmpurile pe care le trimiteți. Intrarea rămâne pe dosarul său. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409. Răspunde cu 404 când intrarea nu este vizibilă.

Domeniu
mail_register:update
Permisiune Flowyer
mail:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

direction
string | null

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD.

subject
string | nullcel puțin 1 caracterecel mult 1000 caractere

Subiect. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
sender
string | nullcel mult 1000 caractere

Feladó: expeditorul (text liber). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
to
string | nullcel mult 1000 caractere

Címzett: destinatarul (text liber). Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
recipient
string | nullcel mult 1000 caractere

Corespondență outgoing: destinatarul în text liber. Nu este permis împreună cu recipient_user_id. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
recipient_user_id
integer | null>= 1

Corespondență incoming: colegul care primește (un id de utilizator), stocat ca recipient numeric. Nu este permis împreună cu recipient.

electronic
boolean | null

Dacă elementul este electronic (type_of_mail).

delivery_method_id
integer | null>= 1

Id-ul metodei de livrare (mail_delivery_methods); 422 când este necunoscut.

tracking_no
string | nullcel mult 255 caractere

Azonosító: numărul de urmărire. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
folder_path
string | nullcel mult 1000 caractere
Model: ^[^<>]*$

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul intrării din registrul de corespondență (folosiți cu mail_register.get / .update).

Exemplu: 4321
matter
object | null

Dosarul pe care este arhivată intrarea.

Câmpurile matter
id
integer
case_number
string
direction
string

incoming = primită, outgoing = trimisă.

Valori permise: "incoming" "outgoing"
date
string <date> | null

Data poștală/înregistrată, YYYY-MM-DD (fără ora din zi).

subject
string | null
sender
string | null

Feladó: expeditorul (text liber).

to
string | null

Címzett: destinatarul (text liber).

recipient
string | null

Pentru o corespondență incoming: numele afișat al colegului care a primit-o. Pentru o corespondență outgoing: destinatarul/primitorul în text liber.

recipient_user_id
integer | null

Setat doar pentru o corespondență incoming al cărei destinatar este un coleg (un id de utilizator); null pentru o corespondență outgoing.

electronic
boolean

True când elementul a fost înregistrat ca electronic (type_of_mail).

delivery_method_id
integer | null

Id-ul metodei de livrare (mail_delivery_methods).

delivery_method
string | null

Eticheta localizată a metodei de livrare (Posta, Cégkapu, Perkapu, ...), sau varianta de rezervă electronic/neelectronic pentru un rând mai vechi.

tracking_no
string | null

Azonosító: numărul de urmărire.

folder_path
string | null
recorded_by_user_id
integer | null

Colegul care a înregistrat intrarea.

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

Transmiteți aceasta către mail_register.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat intrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Comentarii

Listare comentarii de dosar

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

Listează comentariile unui dosar, cele mai vechi primele: id, autor, corp (HTML îmbogățit) și parent_id-ul unui răspuns. Plat, nu imbricat - reconstruiți firele cu un singur nivel din parent_id. Transmiteți top_level_only pentru a exclude răspunsurile. Răspunde cu 404 când dosarul nu este vizibil pentru utilizator.

Domeniu
comments:read
Permisiune Flowyer
cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului (trebuie să fie vizibil).

Exemplu: 1234

Parametri de interogare

top_level_only
boolean

Doar comentariile de nivel superior (exclude răspunsurile). Implicit false.

Implicit: false
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 9876
matter_id
integer

Dosarul (= case_id) de care aparține comentariul.

parent_id
integer | null

Comentariul de nivel superior la care răspunde acesta; null pentru un comentariu de nivel superior. Răspunsurile au un singur nivel de adâncime.

author_user_id
integer | null

Id-ul de utilizator al autorului (null pentru un import mai vechi).

author_name
string | null

Numele afișat al autorului, sau null.

body
string

Comentariul așa cum este stocat: HTML îmbogățit, deja curățat cu HTMLPurifier pentru comentariile scrise prin acest API.

created_at
string <date-time> | null

Când a fost postat comentariul, ISO 8601 în fusul biroului.

updated_at
string <date-time> | null

Token de blocare optimistă: transmiteți-l către comments.update ca expected_updated_at. Nu este un moment de afișare; null pentru un comentariu mai vechi care nu are unul.

edited
boolean

True când comentariul a fost editat de când a fost postat.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Postare comentariu de dosar

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

Postează un comentariu pe un dosar, sau un răspuns de un singur nivel (parent_id = un comentariu de NIVEL SUPERIOR al ACELUIAȘI dosar). Corpul este HTML îmbogățit, igienizat pe partea de server înainte de stocare. Răspunde cu 404 când dosarul nu este vizibil, cu 422 când parent_id nu este un comentariu de nivel superior al dosarului.

Domeniu
comments:create
Permisiune Flowyer
cases:create

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului (trebuie să fie vizibil).

Exemplu: 1234

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

bodyobligatoriu
stringcel puțin 1 caractere

Comentariul, HTML îmbogățit (așa cum îl produce TinyMCE). Curățat pe partea de server cu HTMLPurifier înainte de stocare. Cel mult 100000 de caractere.

Exemplu: "<p>Egyetértek, a határidő tartható.</p>"
parent_id
integer | null>= 1

Răspuns la acest comentariu de NIVEL SUPERIOR al ACELUIAȘI dosar (din comments.list, parent_id = null); omiteți pentru un nou comentariu de nivel superior.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
matter_id
integer

Dosarul (= case_id) de care aparține comentariul.

parent_id
integer | null

Comentariul de nivel superior la care răspunde acesta; null pentru un comentariu de nivel superior. Răspunsurile au un singur nivel de adâncime.

author_user_id
integer | null

Id-ul de utilizator al autorului (null pentru un import mai vechi).

author_name
string | null

Numele afișat al autorului, sau null.

body
string

Comentariul așa cum este stocat: HTML îmbogățit, deja curățat cu HTMLPurifier pentru comentariile scrise prin acest API.

created_at
string <date-time> | null

Când a fost postat comentariul, ISO 8601 în fusul biroului.

updated_at
string <date-time> | null

Token de blocare optimistă: transmiteți-l către comments.update ca expected_updated_at. Nu este un moment de afișare; null pentru un comentariu mai vechi care nu are unul.

edited
boolean

True când comentariul a fost editat de când a fost postat.

created
boolean
Valoare: true
200

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
matter_id
integer

Dosarul (= case_id) de care aparține comentariul.

parent_id
integer | null

Comentariul de nivel superior la care răspunde acesta; null pentru un comentariu de nivel superior. Răspunsurile au un singur nivel de adâncime.

author_user_id
integer | null

Id-ul de utilizator al autorului (null pentru un import mai vechi).

author_name
string | null

Numele afișat al autorului, sau null.

body
string

Comentariul așa cum este stocat: HTML îmbogățit, deja curățat cu HTMLPurifier pentru comentariile scrise prin acest API.

created_at
string <date-time> | null

Când a fost postat comentariul, ISO 8601 în fusul biroului.

updated_at
string <date-time> | null

Token de blocare optimistă: transmiteți-l către comments.update ca expected_updated_at. Nu este un moment de afișare; null pentru un comentariu mai vechi care nu are unul.

edited
boolean

True când comentariul a fost editat de când a fost postat.

created
boolean
Valoare: false
idempotent_replay
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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>"
}'

Exemple de răspuns

{
  "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
}

Editare comentariu propriu de dosar

PATCH /api/agent/comments/{id}

Editează unul dintre comentariile dumneavoastră PROPRII (doar corpul acestuia; HTML îmbogățit, igienizat pe partea de server înainte de stocare). Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409. Răspunde cu 404 pentru un comentariu care nu este al dumneavoastră sau care se află pe un dosar pe care nu îl puteți vedea.

Domeniu
comments:update
Permisiune Flowyer
cases:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

bodyobligatoriu
stringcel puțin 1 caractere

Corpul nou al comentariului, HTML îmbogățit (așa cum îl produce TinyMCE). Curățat pe partea de server cu HTMLPurifier înainte de stocare. Cel mult 100000 de caractere.

Exemplu: "<p>Pontosítás: a határidő november 15.</p>"

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 9876
matter_id
integer

Dosarul (= case_id) de care aparține comentariul.

parent_id
integer | null

Comentariul de nivel superior la care răspunde acesta; null pentru un comentariu de nivel superior. Răspunsurile au un singur nivel de adâncime.

author_user_id
integer | null

Id-ul de utilizator al autorului (null pentru un import mai vechi).

author_name
string | null

Numele afișat al autorului, sau null.

body
string

Comentariul așa cum este stocat: HTML îmbogățit, deja curățat cu HTMLPurifier pentru comentariile scrise prin acest API.

created_at
string <date-time> | null

Când a fost postat comentariul, ISO 8601 în fusul biroului.

updated_at
string <date-time> | null

Token de blocare optimistă: transmiteți-l către comments.update ca expected_updated_at. Nu este un moment de afișare; null pentru un comentariu mai vechi care nu are unul.

edited
boolean

True când comentariul a fost editat de când a fost postat.

updated
boolean
Valoare: true
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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>"
}'

Exemple de răspuns

{
  "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
}

Termene de judecată

Listare termene de judecată ale dosarului

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

Listează termenele de judecată (tárgyalások) ale unui dosar: data, instanța, locul, colegii participanți și judecătorul, cele mai noi primele. Opțional filtrate după un interval de zile from/to sau după updated_since. Răspunde cu 404 când dosarul nu este vizibil pentru utilizator.

Domeniu
trials:read
Permisiune Flowyer
trials:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul dosarului.

Exemplu: 1234

Parametri de interogare

from
string <date>

Doar termenele din această zi sau ulterioare (YYYY-MM-DD), în fusul orar al biroului.

Exemplu: "2026-01-01"
to
string <date>

Doar termenele din această zi sau anterioare (YYYY-MM-DD), în fusul orar al biroului.

Exemplu: "2026-12-31"
updated_since
string <date-time>

Doar termenele modificate la acest moment ISO 8601 sau după el.

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 4321
matter
object

Dosarul (cazul) de care aparține termenul.

Câmpurile matter
id
integer
case_number
string
date
string <date-time> | null

Data și ora termenului, ISO 8601 în fusul orar al biroului. Este stocat în UTC, așa că comparați momente, nu textul orei de perete.

Exemplu: "2026-03-02T09:00:00+01:00"
participation
string | null

Dacă este necesară prezența unui coleg: "required", "not_required", sau null când nu este setat.

Valori permise: "required" "not_required"
court
object | null

Instanța termenului, rezolvată din registrul partajat al instanțelor; null când nu este setată nicio instanță.

Câmpurile court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Întotdeauna "registry": instanța este o referință către registrul partajat al instanțelor (courts.list), nu text liber.

place
string | null

Sala sau locația termenului. Text simplu.

name_of_the_judge
string | null

Numele judecătorului. Text simplu.

notes
string | null

Note în text liber despre termen. Text simplu.

responsibles
object[]

Colegii care participă la termen (id-uri din colleagues.list).

Câmpurile responsibles
user_id
integer
name
string | null
recorded_by
object | null

Colegul care a înregistrat termenul.

Câmpurile recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către trials.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/matters/1234/trials?from=2026-01-01&to=2026-12-31&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere termen de judecată

GET /api/agent/trials/{id}

Returnează un termen de judecată (tárgyalás) cu dosarul său, instanța, colegii participanți și tokenul de blocare updated_at pentru trials.update. Răspunde cu 404 când termenul nu există sau utilizatorul nu îi poate vedea dosarul.

Domeniu
trials:read
Permisiune Flowyer
trials:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul termenului.

Exemplu: 4321

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
matter
object

Dosarul (cazul) de care aparține termenul.

Câmpurile matter
id
integer
case_number
string
date
string <date-time> | null

Data și ora termenului, ISO 8601 în fusul orar al biroului. Este stocat în UTC, așa că comparați momente, nu textul orei de perete.

Exemplu: "2026-03-02T09:00:00+01:00"
participation
string | null

Dacă este necesară prezența unui coleg: "required", "not_required", sau null când nu este setat.

Valori permise: "required" "not_required"
court
object | null

Instanța termenului, rezolvată din registrul partajat al instanțelor; null când nu este setată nicio instanță.

Câmpurile court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Întotdeauna "registry": instanța este o referință către registrul partajat al instanțelor (courts.list), nu text liber.

place
string | null

Sala sau locația termenului. Text simplu.

name_of_the_judge
string | null

Numele judecătorului. Text simplu.

notes
string | null

Note în text liber despre termen. Text simplu.

responsibles
object[]

Colegii care participă la termen (id-uri din colleagues.list).

Câmpurile responsibles
user_id
integer
name
string | null
recorded_by
object | null

Colegul care a înregistrat termenul.

Câmpurile recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către trials.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/trials/4321' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
    }
  }
}

Creare termen de judecată

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

Înregistrează un termen de judecată (tárgyalás) pe un dosar: ora, o instanță opțională (court_id din courts.list), sala, judecătorul, notele și colegii participanți. Dosarul trebuie să fie vizibil și nearhivat; participanții sunt notificați. O oră fără offset este citită în fusul biroului.

Domeniu
trials:create
Permisiune Flowyer
trials:create

Parametri de cale

idobligatoriu
integer>= 1

Dosarul de care aparține termenul (trebuie să fie vizibil și nearhivat).

Exemplu: 1234

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

dateobligatoriu
string <date-time>

Data și ora termenului, ISO 8601. Cu un offset, acesta este respectat; fără unul, este citit în fusul orar al biroului. Stocat în UTC.

Exemplu: "2026-03-02T09:00:00+01:00"
court_id
integer | null>= 1

Instanța termenului: un id din courts.list (registrul partajat al instanțelor). Omiteți când instanța nu este cunoscută.

Exemplu: 42
participation
string | null

Dacă este necesară prezența unui coleg. Omiteți pentru a-l lăsa nesetat.

Valori permise: "required" "not_required"
place
string | nullcel mult 1000 caractere

Sala sau locația termenului. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "II. emelet 205."
name_of_the_judge
string | nullcel mult 255 caractere

Numele judecătorului. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
notes
string | nullcel mult 10000 caractere

Note în text liber despre termen. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
responsible_user_ids
integer[] | null

Id-urile de utilizator ale colegilor (din colleagues.list) care participă la termen.

idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
matter
object

Dosarul (cazul) de care aparține termenul.

Câmpurile matter
id
integer
case_number
string
date
string <date-time> | null

Data și ora termenului, ISO 8601 în fusul orar al biroului. Este stocat în UTC, așa că comparați momente, nu textul orei de perete.

Exemplu: "2026-03-02T09:00:00+01:00"
participation
string | null

Dacă este necesară prezența unui coleg: "required", "not_required", sau null când nu este setat.

Valori permise: "required" "not_required"
court
object | null

Instanța termenului, rezolvată din registrul partajat al instanțelor; null când nu este setată nicio instanță.

Câmpurile court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Întotdeauna "registry": instanța este o referință către registrul partajat al instanțelor (courts.list), nu text liber.

place
string | null

Sala sau locația termenului. Text simplu.

name_of_the_judge
string | null

Numele judecătorului. Text simplu.

notes
string | null

Note în text liber despre termen. Text simplu.

responsibles
object[]

Colegii care participă la termen (id-uri din colleagues.list).

Câmpurile responsibles
user_id
integer
name
string | null
recorded_by
object | null

Colegul care a înregistrat termenul.

Câmpurile recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către trials.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
matter
object

Dosarul (cazul) de care aparține termenul.

Câmpurile matter
id
integer
case_number
string
date
string <date-time> | null

Data și ora termenului, ISO 8601 în fusul orar al biroului. Este stocat în UTC, așa că comparați momente, nu textul orei de perete.

Exemplu: "2026-03-02T09:00:00+01:00"
participation
string | null

Dacă este necesară prezența unui coleg: "required", "not_required", sau null când nu este setat.

Valori permise: "required" "not_required"
court
object | null

Instanța termenului, rezolvată din registrul partajat al instanțelor; null când nu este setată nicio instanță.

Câmpurile court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Întotdeauna "registry": instanța este o referință către registrul partajat al instanțelor (courts.list), nu text liber.

place
string | null

Sala sau locația termenului. Text simplu.

name_of_the_judge
string | null

Numele judecătorului. Text simplu.

notes
string | null

Note în text liber despre termen. Text simplu.

responsibles
object[]

Colegii care participă la termen (id-uri din colleagues.list).

Câmpurile responsibles
user_id
integer
name
string | null
recorded_by
object | null

Colegul care a înregistrat termenul.

Câmpurile recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către trials.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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."
}'

Exemple de răspuns

{
  "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
}

Actualizare termen de judecată

PATCH /api/agent/trials/{id}

Actualizează un termen de judecată (tárgyalás): ora, instanța, locul, judecătorul, notele, indicatorul de prezență și participanții. Scrie doar câmpurile pe care le trimiteți; trimiteți responsible_user_ids pentru a înlocui întreaga listă de participanți. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409.

Domeniu
trials:update
Permisiune Flowyer
trials:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

date
string <date-time>

Noua dată și oră a termenului, ISO 8601 (un offset este respectat, o oră naivă este citită în fusul biroului). Stocat în UTC.

Exemplu: "2026-03-02T09:00:00+01:00"
court_id
integer | null>= 1

Noul id de instanță din courts.list; null pentru a șterge instanța.

participation
string | null

Dacă este necesară prezența unui coleg; null pentru a-l șterge.

Valori permise: "required" "not_required"
place
string | nullcel mult 1000 caractere

Sala sau locația. Text simplu; "<" și ">" nu sunt permise. "" o șterge.

Model: ^[^<>]*$
name_of_the_judge
string | nullcel mult 255 caractere

Numele judecătorului. Text simplu; "<" și ">" nu sunt permise. "" îl șterge.

Model: ^[^<>]*$
notes
string | nullcel mult 10000 caractere

Note în text liber. Text simplu; "<" și ">" nu sunt permise. "" le șterge.

Model: ^[^<>]*$
responsible_user_ids
integer[] | null

Setul complet de înlocuire al id-urilor de utilizator ale participanților (din colleagues.list). Omiteți pentru a lăsa participanții neschimbați.

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
matter
object

Dosarul (cazul) de care aparține termenul.

Câmpurile matter
id
integer
case_number
string
date
string <date-time> | null

Data și ora termenului, ISO 8601 în fusul orar al biroului. Este stocat în UTC, așa că comparați momente, nu textul orei de perete.

Exemplu: "2026-03-02T09:00:00+01:00"
participation
string | null

Dacă este necesară prezența unui coleg: "required", "not_required", sau null când nu este setat.

Valori permise: "required" "not_required"
court
object | null

Instanța termenului, rezolvată din registrul partajat al instanțelor; null când nu este setată nicio instanță.

Câmpurile court
id
integer
name
string
city
string | null
zip
string | null
address
string | null
source
string

Întotdeauna "registry": instanța este o referință către registrul partajat al instanțelor (courts.list), nu text liber.

place
string | null

Sala sau locația termenului. Text simplu.

name_of_the_judge
string | null

Numele judecătorului. Text simplu.

notes
string | null

Note în text liber despre termen. Text simplu.

responsibles
object[]

Colegii care participă la termen (id-uri din colleagues.list).

Câmpurile responsibles
user_id
integer
name
string | null
recorded_by
object | null

Colegul care a înregistrat termenul.

Câmpurile recorded_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către trials.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Instanțe

Listare instanțe

GET /api/agent/courts

Listează registrul partajat al instanțelor (id, nume, oraș) pentru court_id al trials.create / trials.update. Cu q (un nume de instanță așa cum a fost auzit; diacriticele, majusculele/minusculele și micile greșeli de tastare sunt tolerate) răspunde cu statusul exact/similar/none: doar "exact" este sigur de folosit direct. Este directorul instanțelor din Ungaria.

Domeniu
courts:read

Parametri de interogare

q
stringcel mult 255 caractere

Un nume de instanță de căutat, așa cum a fost auzit sau dictat, în orice ordine a cuvintelor. Omiteți-l pentru a lista fiecare instanță.

Exemplu: "Fővárosi Törvényszék"
limit
integer>= 1<= 500

Numărul maxim de instanțe de returnat (implicit 200).

Implicit: 200

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
status
string | null

Doar cu q: exact = o singură potrivire sigură (id-ul ei se poate folosi în siguranță), similar = potrivire aproximativă sau mai multe potriviri (confirmați mai întâi cu utilizatorul), none = nicio potrivire (întrebați utilizatorul). Null fără q.

Valori permise: "exact" "similar" "none"
courts
object[]

Instanțe, cea mai bună potrivire prima cu q, altfel după nume.

Câmpurile courts
id
integer

Id-ul instanței: transmiteți-l ca court_id către trials.create / trials.update.

name
string

Numele instanței așa cum este afișat în Flowyer.

city
string | null
zip
string | null
address
string | null
total
integer

Câte instanțe au corespuns (toate instanțele fără q) înainte ca lista să fie redusă la limit.

truncated
boolean

True când au corespuns mai multe instanțe decât au fost returnate: restrângeți q sau măriți limit.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/courts?q=F%C5%91v%C3%A1rosi%20T%C3%B6rv%C3%A9nysz%C3%A9k' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "data": {
    "status": "exact",
    "courts": [
      {
        "id": 1234,
        "name": "string",
        "city": "string",
        "zip": "string",
        "address": "string"
      }
    ],
    "total": 1,
    "truncated": true
  }
}

HR

Listare concedii ale personalului

GET /api/agent/hr/leaves

Listează concediile aprobate ale personalului (cine este sau va fi în concediu): colegul, datele de început/sfârșit, numărul de zile lucrătoare, o categorie redactată pentru confidențialitate (leave/unpaid; boala este unificată în leave și niciodată identificabilă) și eventualul înlocuitor. Nu returnează niciodată tipul concediului, notele sau cine l-a aprobat.

Domeniu
hr:read
Permisiune Flowyer
hr-admin:read

Parametri de interogare

user_id
integer>= 1

Doar concediile acestui coleg. Un id central de utilizator (din colleagues.list), potrivit cu angajatul din spatele concediului.

Exemplu: 1234
on_date
string <date>

Cine este în concediu în această zi exactă (start_date <= on_date <= end_date). Când este setat, suprascrie date_from, date_to și timeframe.

date_from
string <date>

Doar concediile care sunt încă în desfășurare la această dată sau după ea (end_date >= date_from). Implicit astăzi, astfel încât concediile complet trecute sunt excluse în mod implicit.

date_to
string <date>

Doar concediile care încep la această dată sau înainte de ea (start_date <= date_to). Omiteți pentru un viitor fără limită.

timeframe
string

Constrângere suplimentară a datei de început față de astăzi: current = deja începute (în desfășurare), upcoming = încă neîncepute, all = fără constrângere suplimentară. Ignorată când on_date este setat.

Valori permise: "current" "upcoming" "all"
Implicit: "all"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul cererii de concediu (doar un identificator; nu este sensibil).

user_id
integer

Colegul aflat în concediu (id central de utilizator).

user
string | null

Numele afișat al colegului.

start_date
string <date>

Prima zi de concediu (YYYY-MM-DD).

end_date
string <date>

Ultima zi de concediu, inclusiv (YYYY-MM-DD).

days_count
number | null

Zile lucrătoare de concediu. Nu dezvăluie tipul.

category
string

Tipul de concediu redactat pentru confidențialitate: annual și sick devin ambele "leave" (boala nu este niciodată identificabilă), unpaid rămâne "unpaid". Tipul brut al concediului nu este niciodată expus.

Valori permise: "leave" "unpaid"
status
string

Întotdeauna "approved" - sunt returnate doar concediile aprobate; pending, rejected și cancelled nu apar niciodată.

Valori permise: "approved"
substitute_user_id
integer | null

Colegul care asigură înlocuirea pentru acest concediu (id central de utilizator), sau null.

substitute_user
string | null

Numele afișat al colegului înlocuitor, sau null.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/hr/leaves?user_id=1234&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Calendar

Listare evenimente de calendar

GET /api/agent/calendar/events

Listează evenimentele de calendar care se suprapun cu un interval de date [from, to]: calendarul biroului, cel propriu și calendarele partajate cu dumneavoastră. Evenimentele recurente sunt returnate o singură dată (is_recurring), NU extinse. Ordonate după start. Un eveniment personal nepartajat cu dumneavoastră nu apare niciodată.

Domeniu
calendar:read
Permisiune Flowyer
calendar-office:read

Parametri de interogare

fromobligatoriu
string <date-time>

Începutul intervalului (inclusiv), ISO 8601. Sunt returnate evenimentele care se suprapun cu [from, to]. O oră fără offset este citită în fusul biroului.

Exemplu: "2026-03-01T00:00:00+01:00"
toobligatoriu
string <date-time>

Sfârșitul intervalului (inclusiv), ISO 8601. Trebuie să fie la from sau după el (altfel 422) și cel mult la 366 de zile după el.

Exemplu: "2026-03-31T23:59:59+01:00"
calendar_ids
integer[]

Restrângeți la aceste id-uri de calendar container; fiecare este intersectat cu calendarele pe care le puteți vizualiza, astfel încât un id pe care nu îl puteți vedea este eliminat în tăcere. Omiteți pentru fiecare calendar vizibil.

include_recurring
boolean

Include evenimentele principale recurente a căror regulă se suprapune cu intervalul (returnate neextinse, is_recurring = true). Implicit true.

Implicit: true
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 5501
calendar
object

Calendarul de care aparține evenimentul.

Câmpurile calendar
id
integer | null

Id-ul calendarului container, sau null pentru calendarul partajat al biroului implicit (un eveniment mai vechi fără container).

name
string | null
type
string

"office" = calendarul partajat al biroului (orice utilizator al biroului îl poate vizualiza și edita); "personal" = calendarul propriu al unui utilizator, vizibil doar pentru proprietarul lui și cei cu care este partajat.

Valori permise: "office" "personal"
owner
object | null

Proprietarul unui calendar personal; null pentru calendarul biroului.

Câmpurile owner
user_id
integer
name
string | null
title
string | null

Titlul evenimentului. Text simplu.

description
string | null

Descrierea evenimentului. Text simplu.

location
string | null

Locația. Text simplu.

participants
string | null

Participanți, text liber. Text simplu.

start
string | null

Un eveniment pe toată ziua: data de început "YYYY-MM-DD". Un eveniment cu oră: ISO 8601 în fusul orar al biroului (momentul UTC stocat).

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ (valoarea stocată, nu valoarea +1 zi folosită de o grilă de calendar). Null când evenimentul nu are sfârșit.

all_day
boolean

True pentru un eveniment pe toată ziua (start/end sunt date simple); false pentru un eveniment cu oră (start/end sunt momente ISO 8601).

color
string | null

Culoarea de afișare, de exemplu "#2c7be5".

is_recurring
boolean

True când evenimentul este un eveniment principal recurent. Evenimentele recurente sunt returnate o singură dată, NU extinse în apariții, și nu pot fi modificate prin calendar.events.update.

recurrence
object | null

Regula de recurență a unui eveniment principal recurent, sau null pentru un eveniment singular. Doar pentru citire.

Câmpurile recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Coduri de zile ale săptămânii separate prin virgulă (de exemplu "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Colegul care a creat evenimentul.

Câmpurile created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către calendar.events.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/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_...'

Exemple de răspuns

{
  "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
  }
}

Obținere eveniment de calendar

GET /api/agent/calendar/events/{id}

Returnează un eveniment de calendar cu calendarul său, rezumatul recurenței și tokenul de blocare updated_at pentru calendar.events.update. Răspunde cu 404 când evenimentul nu există sau calendarul său nu este vizibil pentru utilizator.

Domeniu
calendar:read
Permisiune Flowyer
calendar-office:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul evenimentului.

Exemplu: 5501

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 5501
calendar
object

Calendarul de care aparține evenimentul.

Câmpurile calendar
id
integer | null

Id-ul calendarului container, sau null pentru calendarul partajat al biroului implicit (un eveniment mai vechi fără container).

name
string | null
type
string

"office" = calendarul partajat al biroului (orice utilizator al biroului îl poate vizualiza și edita); "personal" = calendarul propriu al unui utilizator, vizibil doar pentru proprietarul lui și cei cu care este partajat.

Valori permise: "office" "personal"
owner
object | null

Proprietarul unui calendar personal; null pentru calendarul biroului.

Câmpurile owner
user_id
integer
name
string | null
title
string | null

Titlul evenimentului. Text simplu.

description
string | null

Descrierea evenimentului. Text simplu.

location
string | null

Locația. Text simplu.

participants
string | null

Participanți, text liber. Text simplu.

start
string | null

Un eveniment pe toată ziua: data de început "YYYY-MM-DD". Un eveniment cu oră: ISO 8601 în fusul orar al biroului (momentul UTC stocat).

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ (valoarea stocată, nu valoarea +1 zi folosită de o grilă de calendar). Null când evenimentul nu are sfârșit.

all_day
boolean

True pentru un eveniment pe toată ziua (start/end sunt date simple); false pentru un eveniment cu oră (start/end sunt momente ISO 8601).

color
string | null

Culoarea de afișare, de exemplu "#2c7be5".

is_recurring
boolean

True când evenimentul este un eveniment principal recurent. Evenimentele recurente sunt returnate o singură dată, NU extinse în apariții, și nu pot fi modificate prin calendar.events.update.

recurrence
object | null

Regula de recurență a unui eveniment principal recurent, sau null pentru un eveniment singular. Doar pentru citire.

Câmpurile recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Coduri de zile ale săptămânii separate prin virgulă (de exemplu "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Colegul care a creat evenimentul.

Câmpurile created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către calendar.events.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/calendar/events/5501' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
    }
  }
}

Creare eveniment de calendar

POST /api/agent/calendar/events

Creează un singur eveniment de calendar (cu oră sau pe toată ziua) în calendarul biroului sau într-un calendar pe care îl puteți edita. Un start/end cu oră respectă un offset ISO 8601, o oră naivă este citită în fusul biroului; o dată de sfârșit pe toată ziua este inclusivă. Evenimentele recurente nu sunt create aici. Nu sunt transmise către calendare externe.

Domeniu
calendar:create
Permisiune Flowyer
calendar-office:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

titleobligatoriu
stringcel puțin 1 caracterecel mult 255 caractere

Titlul evenimentului. Text simplu; "<" și ">" nu sunt permise (acesta trece neescapat în notificarea de memento).

Model: ^[^<>]*$
Exemplu: "Ügyfél egyeztetés"
startobligatoriu
string

Pe toată ziua (all_day true): o dată "YYYY-MM-DD". Cu oră (all_day false): ISO 8601; un offset este respectat, o oră naivă este citită în fusul biroului.

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Implicit = start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ. Nu trebuie să fie înainte de start (altfel 422).

all_day
boolean

Dacă evenimentul este pe toată ziua. Implicit false (cu oră).

Implicit: false
calendar_id
integer | null>= 1

Calendarul container țintă; implicit = calendarul biroului. Trebuie să dețineți drepturi de editare asupra lui (altfel 403). Doar pe un tenant cu funcția de calendar personal.

location
string | nullcel mult 1000 caractere

Locația. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
description
string | nullcel mult 10000 caractere

Descriere, text simplu (nu HTML); "<" și ">" nu sunt permise.

Model: ^[^<>]*$
participants
string | nullcel mult 1000 caractere

Participanți, text liber. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
color
string | nullcel mult 32 caractere

Culoarea de afișare, de exemplu "#2c7be5".

Model: ^#?[A-Za-z0-9_-]{1,31}$
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 5501
calendar
object

Calendarul de care aparține evenimentul.

Câmpurile calendar
id
integer | null

Id-ul calendarului container, sau null pentru calendarul partajat al biroului implicit (un eveniment mai vechi fără container).

name
string | null
type
string

"office" = calendarul partajat al biroului (orice utilizator al biroului îl poate vizualiza și edita); "personal" = calendarul propriu al unui utilizator, vizibil doar pentru proprietarul lui și cei cu care este partajat.

Valori permise: "office" "personal"
owner
object | null

Proprietarul unui calendar personal; null pentru calendarul biroului.

Câmpurile owner
user_id
integer
name
string | null
title
string | null

Titlul evenimentului. Text simplu.

description
string | null

Descrierea evenimentului. Text simplu.

location
string | null

Locația. Text simplu.

participants
string | null

Participanți, text liber. Text simplu.

start
string | null

Un eveniment pe toată ziua: data de început "YYYY-MM-DD". Un eveniment cu oră: ISO 8601 în fusul orar al biroului (momentul UTC stocat).

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ (valoarea stocată, nu valoarea +1 zi folosită de o grilă de calendar). Null când evenimentul nu are sfârșit.

all_day
boolean

True pentru un eveniment pe toată ziua (start/end sunt date simple); false pentru un eveniment cu oră (start/end sunt momente ISO 8601).

color
string | null

Culoarea de afișare, de exemplu "#2c7be5".

is_recurring
boolean

True când evenimentul este un eveniment principal recurent. Evenimentele recurente sunt returnate o singură dată, NU extinse în apariții, și nu pot fi modificate prin calendar.events.update.

recurrence
object | null

Regula de recurență a unui eveniment principal recurent, sau null pentru un eveniment singular. Doar pentru citire.

Câmpurile recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Coduri de zile ale săptămânii separate prin virgulă (de exemplu "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Colegul care a creat evenimentul.

Câmpurile created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către calendar.events.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 5501
calendar
object

Calendarul de care aparține evenimentul.

Câmpurile calendar
id
integer | null

Id-ul calendarului container, sau null pentru calendarul partajat al biroului implicit (un eveniment mai vechi fără container).

name
string | null
type
string

"office" = calendarul partajat al biroului (orice utilizator al biroului îl poate vizualiza și edita); "personal" = calendarul propriu al unui utilizator, vizibil doar pentru proprietarul lui și cei cu care este partajat.

Valori permise: "office" "personal"
owner
object | null

Proprietarul unui calendar personal; null pentru calendarul biroului.

Câmpurile owner
user_id
integer
name
string | null
title
string | null

Titlul evenimentului. Text simplu.

description
string | null

Descrierea evenimentului. Text simplu.

location
string | null

Locația. Text simplu.

participants
string | null

Participanți, text liber. Text simplu.

start
string | null

Un eveniment pe toată ziua: data de început "YYYY-MM-DD". Un eveniment cu oră: ISO 8601 în fusul orar al biroului (momentul UTC stocat).

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ (valoarea stocată, nu valoarea +1 zi folosită de o grilă de calendar). Null când evenimentul nu are sfârșit.

all_day
boolean

True pentru un eveniment pe toată ziua (start/end sunt date simple); false pentru un eveniment cu oră (start/end sunt momente ISO 8601).

color
string | null

Culoarea de afișare, de exemplu "#2c7be5".

is_recurring
boolean

True când evenimentul este un eveniment principal recurent. Evenimentele recurente sunt returnate o singură dată, NU extinse în apariții, și nu pot fi modificate prin calendar.events.update.

recurrence
object | null

Regula de recurență a unui eveniment principal recurent, sau null pentru un eveniment singular. Doar pentru citire.

Câmpurile recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Coduri de zile ale săptămânii separate prin virgulă (de exemplu "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Colegul care a creat evenimentul.

Câmpurile created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către calendar.events.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare eveniment de calendar

PATCH /api/agent/calendar/events/{id}

Actualizează un singur eveniment de calendar: titlul, start/end, all_day, locația, descrierea, participanții, culoarea. Scrie doar câmpurile pe care le trimiteți; "" șterge location/description/participants. Un eveniment recurent răspunde cu 422. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409.

Domeniu
calendar:update
Permisiune Flowyer
calendar-office:modify

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

title
stringcel puțin 1 caracterecel mult 255 caractere

Titlu nou. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
start
string

Start nou. Pe toată ziua: "YYYY-MM-DD". Cu oră: ISO 8601 (un offset respectat, o oră naivă citită în fusul biroului). Recodificat dacă all_day se schimbă.

end
string | null

End nou, aceeași codificare ca start; "" îl șterge. Pentru un eveniment pe toată ziua, data de sfârșit este inclusivă. Nu trebuie să fie înainte de start (altfel 422).

all_day
boolean

Dacă este trimis, start/end sunt recodificate în consecință; dacă este omis, se folosește all_day curent al rândului.

location
string | nullcel mult 1000 caractere

Locația. Text simplu; "<" și ">" nu sunt permise. "" o șterge.

Model: ^[^<>]*$
description
string | nullcel mult 10000 caractere

Descriere, text simplu (nu HTML); "<" și ">" nu sunt permise. "" o șterge.

Model: ^[^<>]*$
participants
string | nullcel mult 1000 caractere

Participanți, text liber. Text simplu; "<" și ">" nu sunt permise. "" îi șterge.

Model: ^[^<>]*$
color
string | nullcel mult 32 caractere

Culoarea de afișare, de exemplu "#2c7be5". "" o șterge.

Model: ^#?[A-Za-z0-9_-]{1,31}$

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 5501
calendar
object

Calendarul de care aparține evenimentul.

Câmpurile calendar
id
integer | null

Id-ul calendarului container, sau null pentru calendarul partajat al biroului implicit (un eveniment mai vechi fără container).

name
string | null
type
string

"office" = calendarul partajat al biroului (orice utilizator al biroului îl poate vizualiza și edita); "personal" = calendarul propriu al unui utilizator, vizibil doar pentru proprietarul lui și cei cu care este partajat.

Valori permise: "office" "personal"
owner
object | null

Proprietarul unui calendar personal; null pentru calendarul biroului.

Câmpurile owner
user_id
integer
name
string | null
title
string | null

Titlul evenimentului. Text simplu.

description
string | null

Descrierea evenimentului. Text simplu.

location
string | null

Locația. Text simplu.

participants
string | null

Participanți, text liber. Text simplu.

start
string | null

Un eveniment pe toată ziua: data de început "YYYY-MM-DD". Un eveniment cu oră: ISO 8601 în fusul orar al biroului (momentul UTC stocat).

Exemplu: "2026-03-02T09:00:00+01:00"
end
string | null

Aceeași codificare ca start. Pentru un eveniment pe toată ziua, data de sfârșit este INCLUSIVĂ (valoarea stocată, nu valoarea +1 zi folosită de o grilă de calendar). Null când evenimentul nu are sfârșit.

all_day
boolean

True pentru un eveniment pe toată ziua (start/end sunt date simple); false pentru un eveniment cu oră (start/end sunt momente ISO 8601).

color
string | null

Culoarea de afișare, de exemplu "#2c7be5".

is_recurring
boolean

True când evenimentul este un eveniment principal recurent. Evenimentele recurente sunt returnate o singură dată, NU extinse în apariții, și nu pot fi modificate prin calendar.events.update.

recurrence
object | null

Regula de recurență a unui eveniment principal recurent, sau null pentru un eveniment singular. Doar pentru citire.

Câmpurile recurrence
freq
string | null

daily | weekly | monthly | yearly.

interval
integer | null
byweekday
string | null

Coduri de zile ale săptămânii separate prin virgulă (de exemplu "MO,WE,FR").

until
string | null
count
integer | null
created_by
object | null

Colegul care a creat evenimentul.

Câmpurile created_by
user_id
integer
name
string | null
created_at
string <date-time> | null
updated_at
string <date-time> | null

Transmiteți aceasta către calendar.events.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat înregistrarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Programări

Listare programări

GET /api/agent/bookings

Listează programările (időpontfoglalások) biroului, cele mai noi primele. Opțional filtrate după un interval de zile from/to (fusul orar al programării), un avocat (user_id), un status sau updated_since. Fiecare deținător de cheie vede programările tuturor avocaților.

Domeniu
bookings:read

Parametri de interogare

from
string <date>

Doar programările din această zi sau ulterioare (YYYY-MM-DD), comparate literal cu data în fusul programării.

Exemplu: "2026-01-01"
to
string <date>

Doar programările din această zi sau anterioare (YYYY-MM-DD).

Exemplu: "2026-12-31"
user_id
integer>= 1

Filtrați la un singur avocat (user_id din colleagues.list). Omiteți pentru fiecare avocat al biroului.

status
string

Filtrați după status.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
updated_since
string <date-time>

Doar programările modificate la acest moment ISO 8601 sau după el (updated_at este o valoare naivă, în fusul biroului).

limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/bookings?from=2026-01-01&to=2026-12-31&limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere programare

GET /api/agent/bookings/{id}

Returnează o programare cu avocatul, detaliile clientului, momentele de început/sfârșit, starea de plată și tokenul de blocare updated_at pentru bookings.update / .confirm / .cancel. Răspunde cu 404 când programarea nu există în acest birou.

Domeniu
bookings:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul programării.

Exemplu: 4321

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/bookings/4321' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
    }
  }
}

Creare programare

POST /api/agent/bookings

Rezervă o programare și TRIMITE UN E-MAIL CLIENTULUI cu confirmarea. Necesită un interval liber pentru avocat (altfel 409); calendarul biroului nu blochează niciodată. source este "manual". O reluare cu Idempotency-Key nici nu reprogramează, nici nu retrimite e-mailul.

Domeniu
bookings:create

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

user_idobligatoriu
integer>= 1

Avocatul cu care este programarea (user_id din colleagues.list; trebuie să fie un coleg activ al biroului).

Exemplu: 42
dateobligatoriu
string <date>

Ziua programării (YYYY-MM-DD) în fusul orar al programării.

Exemplu: "2026-03-02"
timeobligatoriu
string

Ora de început HH:MM (24h) în fusul orar al programării. Ora de sfârșit este time + durata intervalului biroului. Trebuie să fie un interval liber.

Model: ^([01]\d|2[0-3]):[0-5]\d$
Exemplu: "09:00"
client_nameobligatoriu
stringcel mult 255 caractere

Numele clientului. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$
Exemplu: "Kovács Anna"
client_emailobligatoriu
stringcel mult 255 caractere

E-mailul clientului: destinatarul confirmării.

Exemplu: "anna@example.com"
client_phone
string | nullcel mult 50 caractere

Telefonul clientului. Text simplu.

Model: ^[^<>]*$
client_description
string | nullcel mult 2000 caractere

Obiectul / notele de la client. Text simplu.

Model: ^[^<>]*$
location_preference
string

Consultație la birou sau online. Implicit "office".

Valori permise: "office" "online"
Implicit: "office"
meeting_link
string | nullcel mult 500 caractere

URL-ul întâlnirii online (http/https), pentru o consultație online.

gdpr_consent
boolean

Înregistrează consimțământul clientului privind prelucrarea datelor. Implicit true (personalul biroului face programarea în numele clientului).

Implicit: true
auto_confirm
boolean

Când este true (sau biroul are confirmarea automată activată), creează programarea deja confirmată: rulează sincronizarea calendarului și trimite clientului o confirmare în loc de o cerere. În caz contrar, aceasta este pending.

Implicit: false
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Actualizare programare

PATCH /api/agent/bookings/{id}

Reprogramează (date + time împreună, reverificate pentru un interval liber) sau editează o programare (telefon, note, link de întâlnire, locație). Scrie doar câmpurile pe care le trimiteți. Notifică avocatul despre o reprogramare, niciodată clientul. Transmiteți expected_updated_at din ultima citire; o scriere învechită răspunde cu 409.

Domeniu
bookings:update

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

date
string <date>

Ziua nouă (YYYY-MM-DD) în fusul orar al programării. Trimiteți date ȘI time împreună pentru a reprograma.

Exemplu: "2026-03-05"
time
string

Noua oră de început HH:MM. Ora de sfârșit este recalculată din durata intervalului biroului. Trimiteți date ȘI time împreună.

Model: ^([01]\d|2[0-3]):[0-5]\d$
Exemplu: "11:00"
client_phone
string | nullcel mult 50 caractere

Telefonul clientului. Text simplu. "" îl șterge.

Model: ^[^<>]*$
client_description
string | nullcel mult 2000 caractere

Obiectul / notele. Text simplu. "" le șterge.

Model: ^[^<>]*$
meeting_link
string | nullcel mult 500 caractere

URL-ul întâlnirii online (http/https). "" îl șterge.

location_preference
string

Consultație la birou sau online.

Valori permise: "office" "online"

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Confirmare programare

POST /api/agent/bookings/{id}/confirm

Confirmă o programare pending și TRIMITE UN E-MAIL CLIENTULUI cu confirmarea (cu linkul de întâlnire pentru una online). Doar o programare pending poate fi confirmată; orice alt status răspunde cu 409, astfel încât o reîncercare nu retrimite niciodată e-mailul. Opțional, transmiteți expected_updated_at ca token de blocare.

Domeniu
bookings:send

Parametri de cale

idobligatoriu
integer>= 1

Id-ul programării.

Exemplu: 4321

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Token opțional de blocare optimistă: updated_at din ultima citire. Dacă programarea s-a schimbat între timp, API-ul răspunde cu 409 și o recitiți înainte de a reîncerca.

meeting_link
string | nullcel mult 500 caractere

URL-ul întâlnirii online (http/https) de setat pe programare înainte de trimiterea e-mailului de confirmare.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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"
    }
  }
}

Anulare programare

POST /api/agent/bookings/{id}/cancel

Anulează o programare și TRIMITE UN E-MAIL CLIENTULUI (și avocatului) cu anularea. O programare deja cancelled sau completed răspunde cu 409, astfel încât o reîncercare nu retrimite niciodată e-mailul. O programare plătită este anulată, dar niciodată rambursată (biroul se ocupă de acest lucru). Opțional, transmiteți expected_updated_at.

Domeniu
bookings:send

Parametri de cale

idobligatoriu
integer>= 1

Id-ul programării.

Exemplu: 4321

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Token opțional de blocare optimistă: updated_at din ultima citire. Dacă programarea s-a schimbat între timp, API-ul răspunde cu 409.

reason
string | nullcel mult 255 caractere

Motivul înregistrat ca cancel_reason și afișat în e-mailul de anulare. Text simplu; "<" și ">" nu sunt permise.

Model: ^[^<>]*$

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer
Exemplu: 4321
booking_number
string

Numărul lizibil al programării, de exemplu "#B-0001".

status
string

pending = așteaptă confirmarea avocatului; confirmed = aprobată; cancelled/completed; awaiting_payment/expired aparțin fluxului de plată înainte de confirmare.

Valori permise: "pending" "confirmed" "cancelled" "completed" "awaiting_payment" "expired"
source
string

De unde provine programarea. O programare creată prin API este "manual".

Valori permise: "flowyer" "website" "embed_widget" "manual"
lawyer
object | null

Avocatul (user_id din colleagues.list) cu care este programarea.

Câmpurile lawyer
user_id
integer
name
string | null
date
string <date> | null

Data calendaristică în fusul orar al programării (YYYY-MM-DD), stocată literal.

start_time
string | null

Ora de început HH:MM în fusul orar al programării.

end_time
string | null

Ora de sfârșit HH:MM în fusul orar al programării.

start
string <date-time> | null

Momentul ISO 8601 neambiguu al începutului, compus cu fusul orar al programării. Folosiți-l pentru a compara momente între fusuri.

end
string <date-time> | null

Momentul ISO 8601 neambiguu al sfârșitului.

timezone
string

Fusul orar al programării (booking_settings.timezone), de exemplu "Europe/Budapest". Acesta guvernează date, start_time și end_time.

location_preference
string

Dacă consultația are loc la birou sau online.

Valori permise: "office" "online"
meeting_link
string | null

URL-ul întâlnirii online, când este setat.

client
object

Clientul extern care a făcut programarea: nume, e-mail, telefon și obiectul/notele. Date cu caracter personal - doar pentru personalul biroului.

Câmpurile client
name
string | null
email
string | null
phone
string | null
description
string | null
gdpr_consent
boolean

Dacă este înregistrat consimțământul clientului privind prelucrarea datelor.

gdpr_consent_at
string <date-time> | null

Când a fost înregistrat consimțământul.

cancel_reason
string | null

Motivul înregistrat la anulare.

payment
object

Starea de plată, doar pentru citire. API-ul nu modifică niciodată plata; taxele de programare sunt gestionate în Flowyer.

Câmpurile payment
status
string
Valori permise: "none" "awaiting" "partial" "paid" "refunded"
method
string | null
Valori permise: "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

Transmiteți aceasta către bookings.update / bookings.confirm / bookings.cancel ca expected_updated_at.

created_via_api
object | null

Prezent atunci când un agent extern a creat programarea prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Scope lipsă (scope_missing), API dezactivat pentru birou, licență expirată sau birou arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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"
    }
  }
}

Tichete de asistență

Listare tichete de asistență

GET /api/agent/tickets

Listează tichetele de asistență pe care utilizatorul le poate vedea (vizibilitate per căsuță poștală), cea mai recentă activitate prima. Filtrați după status (implicit open_states = new+open+pending; "all" include și cele închise), căsuță poștală, responsabil, e-mailul solicitantului sau text liber în subiect/solicitant/numărul tichetului.

Domeniu
tickets:read
Permisiune Flowyer
ticketing:read

Parametri de interogare

status
string

open_states (implicit) = new+open+pending (vizualizarea implicită din web); "all" include și cele închise; sau un status exact.

Valori permise: "new" "open" "pending" "closed" "open_states" "all"
Implicit: "open_states"
mailbox_id
integer>= 1

Doar tichetele din această căsuță poștală. O căsuță poștală pe care utilizatorul nu o poate vedea produce o listă goală (niciodată o scurgere).

Exemplu: 7
assigned_to_user_id
integer>= 0

Doar tichetele atribuite acestui coleg (id din colleagues.list); 0 = doar tichetele neatribuite. Omiteți pentru orice responsabil.

requester_email
stringcel mult 255 caractere

Doar tichetele al căror e-mail al solicitantului extern se potrivește exact (fără sensibilitate la majuscule/minuscule).

Exemplu: "ugyfel@example.com"
q
stringcel mult 100 caractere

Căutare text liber în subiect, numele/e-mailul solicitantului și numărul tichetului (ignorând majusculele/minusculele).

Exemplu: "számla"
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul tichetului (folosiți cu tickets.get / tickets.update).

Exemplu: 4321
ticket_number
string | null

Numărul lizibil al tichetului, de exemplu FLW-000123.

subject
string | null
status
string
Valori permise: "new" "open" "pending" "closed"
priority
string
Valori permise: "low" "normal" "high"
mailbox
object | null

Căsuța poștală prin care a sosit tichetul (registru central).

Câmpurile mailbox
id
integer
email
string | null
display_name
string | null
requester
object

Persoana externă care a scris.

Câmpurile requester
email
string | null
name
string | null
assigned_to
object | null

Colegul căruia îi este atribuit tichetul, sau null când este neatribuit.

Câmpurile assigned_to
user_id
integer
name
string | null
matter
object | null

Dosarul legat de tichet, sau null.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul legat de tichet, sau null.

Câmpurile client
id
integer
name
string
last_message_at
string <date-time> | null

Momentul celei mai recente activități din fir; lista este ordonată după acesta, cele mai noi primele.

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

Transmiteți aceasta către tickets.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când tichetul a fost creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/tickets?mailbox_id=7&requester_email=ugyfel%40example.com&q=sz%C3%A1mla' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Obținere tichet de asistență

GET /api/agent/tickets/{id}

Returnează un tichet de asistență cu firul său de mesaje (cele mai vechi primele) și dosarul/clientul legat. Răspunde cu 404 când tichetul nu există sau se află într-o căsuță poștală pe care utilizatorul nu o poate vedea. Citirea nu modifică niciodată tichetul (un tichet NEW nu este trecut la OPEN).

Domeniu
tickets:read
Permisiune Flowyer
ticketing:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul tichetului.

Exemplu: 4321

Parametri de interogare

messages_limit
integer | null>= 1<= 500

Returnează doar cele mai noi N mesaje ale firului (prezentate totuși cele mai vechi primele). Omiteți pentru întregul fir.

Răspunsuri

200

OK.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul tichetului (folosiți cu tickets.get / tickets.update).

Exemplu: 4321
ticket_number
string | null

Numărul lizibil al tichetului, de exemplu FLW-000123.

subject
string | null
status
string
Valori permise: "new" "open" "pending" "closed"
priority
string
Valori permise: "low" "normal" "high"
mailbox
object | null

Căsuța poștală prin care a sosit tichetul (registru central).

Câmpurile mailbox
id
integer
email
string | null
display_name
string | null
requester
object

Persoana externă care a scris.

Câmpurile requester
email
string | null
name
string | null
assigned_to
object | null

Colegul căruia îi este atribuit tichetul, sau null când este neatribuit.

Câmpurile assigned_to
user_id
integer
name
string | null
matter
object | null

Dosarul legat de tichet, sau null.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul legat de tichet, sau null.

Câmpurile client
id
integer
name
string
last_message_at
string <date-time> | null

Momentul celei mai recente activități din fir; lista este ordonată după acesta, cele mai noi primele.

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

Transmiteți aceasta către tickets.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când tichetul a fost creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

user_id
integer
user
string | null
at
string <date-time> | null
messages
object[]

Firul de mesaje, cele mai vechi primele.

Câmpurile messages
id
integer
direction
string

in = de la solicitant, out = răspuns/confirmare automată trimis din căsuța poștală, note = intern.

Valori permise: "in" "out" "note"
from
object
Câmpurile from
email
string | null
name
string | null
to
object[]
Câmpurile to
email
string
name
string | null
cc
object[]
Câmpurile cc
email
string
name
string | null
sent_status
string | null

Starea de livrare a unui mesaj de ieșire; null pentru in/note.

Valori permise: "pending" "sent" "failed" "scheduled"
body_html
string | null

Corpul mesajului ca HTML igienizat (deja sigur la stocare).

body_text
string | null
has_attachments
boolean
author
object | null

Colegul care a scris un mesaj out/note; null pentru un mesaj primit.

Câmpurile author
user_id
integer
name
string | null
created_at
string <date-time> | null
linked_matter
object | null

Dosarul legat de tichet (la fel ca matter).

Câmpurile linked_matter
id
integer
case_number
string
linked_client
object | null

Clientul legat de tichet (la fel ca client).

Câmpurile linked_client
id
integer
name
string
400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/tickets/4321' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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"
    }
  }
}

Răspuns la tichet

POST /api/agent/tickets/{id}/reply

Răspunde la un tichet de asistență și TRIMITE răspunsul prin e-mail către solicitantul extern (prin căsuța poștală a tichetului). Corpul este HTML îmbogățit, igienizat pe partea de server înainte de stocare. O reîncercare cu același Idempotency-Key nu trimite niciodată un al doilea e-mail.

Domeniu
tickets:reply
Permisiune Flowyer
ticketing:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul tichetului (trebuie să fie vizibil prin ACL-ul căsuței poștale).

Exemplu: 4321

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

body_htmlobligatoriu
stringcel puțin 1 caractere

Răspunsul, HTML îmbogățit (așa cum îl produce TinyMCE). Curățat pe partea de server cu HTMLPurifier înainte de stocare și înainte de trimitere. Cel mult 100000 de caractere; respins dacă prin igienizare nu rămâne nimic.

Exemplu: "<p>Köszönjük megkeresését, csatoltan küldjük a választ.</p>"
cc
string[]cel mult 10 elemente

Destinatari Cc suplimentari (cel mult 10). Solicitantul și căsuța poștală sunt excluse automat; o adresă invalidă răspunde cu 422.

status
string

Statusul tichetului de setat după răspuns (implicit "pending" = în așteptarea solicitantului). Înregistrează un eveniment de schimbare a statusului.

Valori permise: "new" "open" "pending" "closed"
Implicit: "pending"
append_signature
boolean

Adaugă semnătura de tichet salvată a utilizatorului cheii doar la e-mailul de IEȘIRE (niciodată stocată în fir).

Implicit: false
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
ticket_id
integer
Exemplu: 4321
message_id
integer

Id-ul rândului ticket_messages de ieșire creat.

Exemplu: 98765
direction
string

Întotdeauna "out".

sent_status
string | null

"pending" la momentul creării; trimiterea asincronă îl schimbă ulterior la sent/failed.

Valori permise: "pending" "sent" "failed" "scheduled"
status
string

Statusul tichetului după răspuns.

Valori permise: "new" "open" "pending" "closed"
created_at
string <date-time> | null
created_via_api
object | null

Prezent atunci când răspunsul a fost creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
ticket_id
integer
Exemplu: 4321
message_id
integer

Id-ul rândului ticket_messages de ieșire creat.

Exemplu: 98765
direction
string

Întotdeauna "out".

sent_status
string | null

"pending" la momentul creării; trimiterea asincronă îl schimbă ulterior la sent/failed.

Valori permise: "pending" "sent" "failed" "scheduled"
status
string

Statusul tichetului după răspuns.

Valori permise: "new" "open" "pending" "closed"
created_at
string <date-time> | null
created_via_api
object | null

Prezent atunci când răspunsul a fost creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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>"
}'

Exemple de răspuns

{
  "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
}

Schimbare status tichet

PATCH /api/agent/tickets/{id}

Schimbă statusul unui tichet (new, open, pending sau closed). "closed" marchează closed_at; orice alt status îl șterge. Transmiteți expected_updated_at din ultima citire; o modificare conflictuală răspunde cu 409. Răspunde cu 404 când tichetul nu este vizibil.

Domeniu
tickets:update
Permisiune Flowyer
ticketing:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul înregistrării de modificat.

Corpul cererii application/json

expected_updated_at
string <date-time> | null

Valoarea updated_at din cea mai recentă citire a acestei înregistrări (obligatorie ori de câte ori înregistrarea are una). Dacă înregistrarea s-a schimbat între timp (un coleg a editat-o), API-ul răspunde cu 409 și trebuie să o recitiți înainte de a reîncerca. O înregistrare veche al cărei updated_at este null acceptă null.

statusobligatoriu
string

Noul status. "closed" marchează closed_at; orice alt status îl șterge.

Valori permise: "new" "open" "pending" "closed"
Exemplu: "open"

Răspunsuri

200

Actualizat.

dataobligatoriu
object
Câmpurile data
id
integer

Id-ul tichetului (folosiți cu tickets.get / tickets.update).

Exemplu: 4321
ticket_number
string | null

Numărul lizibil al tichetului, de exemplu FLW-000123.

subject
string | null
status
string
Valori permise: "new" "open" "pending" "closed"
priority
string
Valori permise: "low" "normal" "high"
mailbox
object | null

Căsuța poștală prin care a sosit tichetul (registru central).

Câmpurile mailbox
id
integer
email
string | null
display_name
string | null
requester
object

Persoana externă care a scris.

Câmpurile requester
email
string | null
name
string | null
assigned_to
object | null

Colegul căruia îi este atribuit tichetul, sau null când este neatribuit.

Câmpurile assigned_to
user_id
integer
name
string | null
matter
object | null

Dosarul legat de tichet, sau null.

Câmpurile matter
id
integer
case_number
string
client
object | null

Clientul legat de tichet, sau null.

Câmpurile client
id
integer
name
string
last_message_at
string <date-time> | null

Momentul celei mai recente activități din fir; lista este ordonată după acesta, cele mai noi primele.

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

Transmiteți aceasta către tickets.update ca expected_updated_at.

created_via_api
object | null

Prezent atunci când tichetul a fost creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Înregistrarea s-a schimbat de când ați citit-o (record_conflict: expected_updated_at nu mai corespunde; citiți-o din nou și reîncercați cu noul updated_at).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X PATCH 'https://www.flowyer.ro/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"
}'

Exemple de răspuns

{
  "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
}

Portal clienți

Listare portaluri client

GET /api/agent/portals

Listează portalurile client (firele) la care utilizatorul are acces: dosarul, participanții din partea clientului, numărul de mesaje și de participanți și ora ultimului mesaj, cele mai noi primele. Opțional filtrate la un singur dosar (matter_id). Un dosar are cel mult un portal.

Domeniu
portal:read
Permisiune Flowyer
client-portal:read, cases:read

Parametri de interogare

matter_id
integer>= 1

Doar portalul acestui dosar (404 matter_not_visible când dosarul nu este vizibil). Un dosar are cel mult un portal.

Exemplu: 1234
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

Id-ul portalului (firului) - identificatorul pentru portal.messages.list și portal.reply.

Exemplu: 57
matter
object

Dosarul (cazul) de care aparține portalul.

Câmpurile matter
id
integer
case_number
string
client_participants
object[]

Participanții externi din partea clientului cu care discută firma.

Câmpurile client_participants
name
string | null
kind
string

client = un mandant, contact = o persoană de contact a clientului, email = un acces mai vechi doar prin e-mail.

Valori permise: "client" "contact" "email"
participant_count
integer

Numărul de participanți activi (personal și client).

message_count
integer

Numărul de mesaje neșterse din fir.

last_message_at
string <date-time> | null

Când a fost postat cel mai nou mesaj neșters, ISO 8601 în fusul biroului; null pentru un fir gol.

unread_for_me
integer | null

Mesaje necitite pentru propriul rând de participant al utilizatorului care acționează; null când utilizatorul care acționează nu este participant al acestui portal.

created_at
string <date-time> | null
paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

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

Exemple de răspuns

{
  "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
  }
}

Listare mesaje de portal

GET /api/agent/portals/{id}/messages

Listează mesajele unui fir de portal client, cele mai vechi primele, cu autorul (personal sau client), corpul în text simplu și eventualele metadate ale atașamentelor. Răspunde cu 404 când portalul nu există sau nu este accesibil. Nu marchează mesajele ca citite.

Domeniu
portal:read
Permisiune Flowyer
client-portal:read, cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul portalului (trebuie să fie accesibil).

Exemplu: 57

Parametri de interogare

include_deleted
boolean

Include mesajele șterse (corpul lor este golit). Implicit false.

Implicit: false
limit
integer>= 1<= 100

Dimensiunea paginii, 1-100. Valoarea implicită este 25.

Implicit: 25
Exemplu: 25
offset
integer>= 0

Numărul de înregistrări de omis. Folosiți offset + limit ale paginii anterioare pentru a o obține pe următoarea; pagination.total este numărul total.

Implicit: 0
Exemplu: 0

Răspunsuri

200

OK.

dataobligatoriu
object[]
Câmpurile data
id
integer

portal_messages.id.

Exemplu: 8012
author
object

Cine a scris mesajul.

Câmpurile author
participant_id
integer | null
name
string | null
kind
string

staff = un coleg al firmei, client = clientul extern.

Valori permise: "staff" "client"
direction
string

from_firm = un autor din personal, from_client = clientul extern.

Valori permise: "from_firm" "from_client"
body
string

Mesajul în text simplu (<br> decodat în întreruperi de linie). Șir gol pentru un mesaj șters.

attachment
object | null

Metadatele atașamentului când mesajul are un document; descărcarea lui este în afara domeniului. Null când nu există niciunul.

Câmpurile attachment
portal_document_id
integer
file_name
string
is_deleted
boolean
deleted_at
string <date-time> | null
created_at
string <date-time> | null

Când a fost postat mesajul, ISO 8601 în fusul biroului.

paginationobligatoriu
object
Câmpurile pagination
limitobligatoriu
integer
offsetobligatoriu
integer
totalobligatoriu
integer

Numărul total de înregistrări care se potrivesc.

400

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl 'https://www.flowyer.ro/api/agent/portals/57/messages?limit=25' \
  -H 'Authorization: Bearer flw_...'

Exemple de răspuns

{
  "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
  }
}

Răspuns în portalul client

POST /api/agent/portals/{id}/messages

Postează un răspuns al personalului într-un fir de portal client. Clientul îl vede în portal și este notificat prin e-mail (o înștiințare cu magic-link semnat, nu textul); colegii primesc o înștiințare în aplicație. Text simplu, escapat la stocare. 404 când portalul nu este accesibil.

Domeniu
portal:reply
Permisiune Flowyer
client-portal:read, cases:read

Parametri de cale

idobligatoriu
integer>= 1

Id-ul portalului în care se răspunde (trebuie să fie accesibil).

Exemplu: 57

Parametri de antet

Idempotency-Key
stringcel mult 128 caractere

Recomandat la fiecare creare. O valoare unică per operație logică (de exemplu un UUID). Aceeași valoare returnează aceeași înregistrare: reîncercarea cu ea returnează înregistrarea creată prima dată, în loc să creeze o a doua. Valori diferite creează întotdeauna înregistrări diferite. Clienții care nu pot trimite anteturi pot transmite aceeași valoare în câmpul de corp idempotency_key. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Corpul cererii application/json

bodyobligatoriu
stringcel puțin 1 caracterecel mult 20000 caractere

Răspunsul, text simplu. Parantezele unghiulare sunt acceptate și escapate la stocare. Cel mult 20000 de caractere.

Exemplu: "Tisztelt Ügyfelünk! A beadványt ma benyújtottuk."
idempotency_key
stringcel mult 128 caractere

Același rol ca antetul Idempotency-Key, pentru clienții care nu pot trimite anteturi personalizate. Litere, cifre, _, -, : sau ., cel mult 128 de caractere.

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

Răspunsuri

201

Creat.

dataobligatoriu
object
Câmpurile data
message
object

Răspunsul postat.

Câmpurile message
id
integer
Exemplu: 8012
author
object

Utilizatorul din personal care a postat răspunsul.

Câmpurile author
participant_id
integer | null
name
string | null
kind
string

staff = un coleg al firmei, client = clientul extern.

Valori permise: "staff" "client"
direction
string

Întotdeauna "from_firm" pentru un răspuns postat prin acest API.

Valori permise: "from_firm" "from_client"
body
string

Mesajul postat în text simplu.

created_at
string <date-time> | null
portal
object

Portalul (firul) și dosarul său în care a fost postat răspunsul.

Câmpurile portal
id
integer
matter
object
Câmpurile matter
id
integer
case_number
string
created_via_api
object | null

Proveniența mesajului creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Reluare idempotentă: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică în interval de 120 de secunde) a creat deja înregistrarea; aceasta este returnată din nou, nu s-a creat nimic nou.

dataobligatoriu
object
Câmpurile data
message
object

Răspunsul postat.

Câmpurile message
id
integer
Exemplu: 8012
author
object

Utilizatorul din personal care a postat răspunsul.

Câmpurile author
participant_id
integer | null
name
string | null
kind
string

staff = un coleg al firmei, client = clientul extern.

Valori permise: "staff" "client"
direction
string

Întotdeauna "from_firm" pentru un răspuns postat prin acest API.

Valori permise: "from_firm" "from_client"
body
string

Mesajul postat în text simplu.

created_at
string <date-time> | null
portal
object

Portalul (firul) și dosarul său în care a fost postat răspunsul.

Câmpurile portal
id
integer
matter
object
Câmpurile matter
id
integer
case_number
string
created_via_api
object | null

Proveniența mesajului creat prin acest API.

Câmpurile created_via_api
kind
string

"key": creat cu o cheie API statică; "oauth": creat de o aplicație conectată prin OAuth.

Valori permise: "key" "oauth"
key_id
integer

Id-ul cheii API (de tipul "key") sau al aplicației conectate (de tipul "oauth"); cele două sunt numerotate separat.

key_name
string

Numele pe care utilizatorul l-a dat cheii API, de exemplu "Grok integration", sau numele aplicației conectate pentru tipul "oauth", de exemplu "Claude".

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

Cerere malformată: corp JSON invalid, host greșit (folosiți hostul www.) sau o cerere care nu poate fi citită.

401

Cheia lipsește, este invalidă, revocată sau expirată, ori utilizatorul ei nu mai este activ.

403

Lipsește un scope (scope_missing), lipsește o permisiune de modul Flowyer (module_forbidden), API-ul este dezactivat pentru birou, licența a expirat sau biroul este arhivat.

404

Endpoint necunoscut sau înregistrarea nu există / nu este vizibilă pentru utilizator. replay_not_visible: acest Idempotency-Key (sau, în lipsa unei chei, o cerere identică) a creat deja înregistrarea (details.record_id), dar aceasta a fost între timp ștearsă sau nu este vizibilă pentru utilizator; nu s-a creat nimic nou, nu o creați din nou.

405

Metodă neoferită pe această cale (DELETE și PUT nu sunt niciodată oferite; PATCH doar acolo unde se oferă o actualizare).

409

Idempotency-Key a fost folosit pentru alt tip de resursă (idempotency_key_reused) sau, în lipsa unei chei, o cerere identică este procesată chiar acum (duplicate_in_progress; reîncercați în scurt timp).

413

Corpul cererii este prea mare (request_too_large).

422

Validarea a eșuat sau câmp necunoscut; details.fields listează erorile de câmp.

429

Limita de rată a fost depășită; Retry-After indică momentul reîncercării.

503

Biroul este temporar indisponibil (întreținere sau configurare în curs); Retry-After indică momentul reîncercării.

default

Orice altă eroare, în același plic de răspuns.

Exemple de cerere

curl -X POST 'https://www.flowyer.ro/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."
}'

Exemple de răspuns

{
  "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
}