e-bon
e-bon.ro
Referință API

API Organizații și Locații

Endpoint-uri REST pentru gestionarea profilului organizației (nume, adresă de facturare), a locațiilor sale și a listei de abonați la notificări.

Organizații și Locații

API-ul de organizații acoperă cele opt endpoint-uri sub /api/v1/org care citesc și scriu profilul propriu al organizației și subcolecția locations. Folosește-l ca să obții profilul organizației, să redenumești organizația, să editezi adresa de facturare folosită pe facturi, să administrezi lista de locații fizice la care sunt atașate dispozitivele și să configurezi cine primește notificări prin email pentru rapoarte, alerte, evenimente de facturare, evenimente de dispozitiv și analize.

Spre deosebire de Bonuri, Dispozitive și Rapoarte, nicio rută din această pagină nu acceptă o cheie API. Toată suprafața /api/v1/org necesită un token de sesiune din Portal. Generează unul cu POST /api/v1/auth/login și trimite-l ca Authorization: Bearer <jwt>. Nu există nicio permisiune de cheie API care să dea acces la administrarea organizației. Vezi Autentificare › Autentificare JWT.

Plicul de eroare, limitele de rată și convențiile de paginare sunt documentate o singură dată pe Prezentarea API-ului; pe această pagină listăm doar codurile de eroare specifice fiecărui endpoint.

GET /api/v1/org

Returnează documentul organizației pentru utilizatorul autentificat (rezolvat din claim-ul orgId al JWT-ului).

Autentificare: JWT din Portal (orice membru al organizației)

Răspuns 200

{
  "id": "acme_corp",
  "name": "Acme Corp SRL",
  "cui": "RO12345678",
  "billingAddress": {
    "country": "Romania",
    "county": "București",
    "city": "București",
    "street": "Str. Lipscani 12, ap. 4",
    "postalCode": "030031"
  },
  "plan": "pro",
  "createdAt": "2025-09-01T08:00:00.000Z",
  "updatedAt": "2026-04-01T12:30:00.000Z"
}

Setul exact de câmpuri depinde de ce este stocat — cui, plan, billingAddress și orice alte metadate la nivel de organizație sunt returnate neschimbate. Toate marcajele de timp sunt returnate ca șiruri ISO-8601.

Erori

  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • NOT_FOUND (404) — orgId-ul din JWT nu se rezolvă într-o organizație. În mod normal apare doar după o ștergere manuală a datelor.

Catalogul HTTP complet este pe Prezentare API › Catalogul codurilor de eroare HTTP.

Exemplu

curl https://api.e-bon.ro/api/v1/org \
  -H "Authorization: Bearer <portal-jwt>"

PATCH /api/v1/org

Actualizează numele afișat al organizației și/sau adresa de facturare. Cel puțin un câmp trebuie furnizat. Celelalte câmpuri ale organizației (cui, plan, createdAt, …) nu pot fi editate prin acest endpoint.

Autentificare: JWT din Portal, rol Owner sau Admin

Corpul cererii

CâmpTipObligatoriuNote
namestringnu1–255 caractere. Șirul gol este respins.
billingAddressobjectnuToate sub-câmpurile sunt opționale. Trimiterea obiectului înlocuiește pe cel anterior.
billingAddress.countrystringnu≤ 100 caractere.
billingAddress.countystringnu≤ 100 caractere.
billingAddress.citystringnu≤ 100 caractere.
billingAddress.streetstringnu≤ 300 caractere.
billingAddress.postalCodestringnu≤ 20 caractere.

Schema impune ca corpul să nu fie gol — cel puțin unul dintre name sau billingAddress trebuie să fie prezent.

Răspuns 200

Documentul actualizat al organizației, în aceeași formă ca GET /api/v1/org.

Erori

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea sau nu s-a furnizat niciun câmp.
  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.
  • NOT_FOUND (404) — organizația nu există.

Exemplu

curl -X PATCH https://api.e-bon.ro/api/v1/org \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp SRL",
    "billingAddress": {
      "country": "Romania",
      "county": "București",
      "city": "București",
      "street": "Str. Lipscani 12, ap. 4",
      "postalCode": "030031"
    }
  }'

GET /api/v1/org/locations

Returnează fiecare locație care aparține organizației utilizatorului autentificat, ordonată descrescător după createdAt (cele mai recent create întâi). Fiecare dispozitiv din e-bon este atașat unei singure locații, iar fiecare bon moștenește locația dispozitivului, deci această listă este registrul canonic „unde îți desfășori activitatea”.

Autentificare: JWT din Portal (orice membru al organizației)

Răspuns 200

[
  {
    "id": "loc_main",
    "name": "Sediu principal",
    "address": "Str. Lipscani 12, București",
    "orgId": "acme_corp",
    "createdAt": "2025-09-01T08:00:00.000Z",
    "updatedAt": "2026-02-15T10:00:00.000Z"
  },
  {
    "id": "loc_warehouse",
    "name": "Depozit Pipera",
    "address": "Bd. Pipera 21, Voluntari",
    "orgId": "acme_corp",
    "createdAt": "2025-10-10T08:00:00.000Z",
    "updatedAt": "2025-10-10T08:00:00.000Z"
  }
]

Endpoint-ul returnează întotdeauna un tablou — fără paginare. Dacă organizația ta nu are locații, răspunsul este [].

Erori

  • UNAUTHORIZED (401) — JWT lipsă sau invalid.

Exemplu

curl https://api.e-bon.ro/api/v1/org/locations \
  -H "Authorization: Bearer <portal-jwt>"

POST /api/v1/org/locations

Creează o nouă locație în organizație. orgId-ul locației este setat automat din JWT — nu există nicio cale de a crea o locație în altă organizație.

Autentificare: JWT din Portal, rol Owner sau Admin

Corpul cererii

CâmpTipObligatoriuNote
namestringda1–255 caractere.
addressstringda1–500 caractere.

Răspuns 201

{
  "id": "loc_warehouse",
  "name": "Depozit Pipera",
  "address": "Bd. Pipera 21, Voluntari",
  "orgId": "acme_corp",
  "createdAt": "2026-04-09T08:10:00.000Z",
  "updatedAt": "2026-04-09T08:10:00.000Z"
}

Răspunsul include marcaje de timp ISO-8601 pentru locația nou creată.

Erori

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea (câmp lipsă, lungime în afara intervalului).
  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.

Exemplu

curl -X POST https://api.e-bon.ro/api/v1/org/locations \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Depozit Pipera",
    "address": "Bd. Pipera 21, Voluntari"
  }'

PATCH /api/v1/org/locations/{locationId}

Actualizează numele și/sau adresa unei locații existente. Cel puțin un câmp trebuie furnizat.

Autentificare: JWT din Portal, rol Owner sau Admin

Parametri de cale

ParametruTipNote
locationIdstringID-ul returnat de POST /locations sau GET /locations.

Corpul cererii

CâmpTipObligatoriuNote
namestringnu1–255 caractere. Șirul gol este respins.
addressstringnu1–500 caractere. Șirul gol este respins.

Răspuns 200

Documentul actualizat al locației, aceeași formă ca elementele din GET /api/v1/org/locations.

Erori

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea sau nu s-a furnizat niciun câmp.
  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.
  • NOT_FOUND (404) — nicio locație cu acel ID în organizația ta.

Exemplu

curl -X PATCH https://api.e-bon.ro/api/v1/org/locations/loc_warehouse \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Depozit Pipera (etaj 2)" }'

DELETE /api/v1/org/locations/{locationId}

Șterge definitiv o locație. Cererea este respinsă dacă vreun dispozitiv este alocat în prezent locației — mută sau șterge mai întâi acele dispozitive prin API-ul de dispozitive.

Autentificare: JWT din Portal, rol Owner sau Admin

Parametri de cale

ParametruTipNote
locationIdstringLocația de șters.

Răspuns 204

Corp gol în caz de succes.

Erori

  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.
  • NOT_FOUND (404) — nicio locație cu acel ID în organizația ta.
  • CONFLICT (409) — unul sau mai multe dispozitive sunt încă alocate locației. Mesajul de eroare include numărul, ex. Cannot delete location — it has 3 device(s) assigned. Move or delete the devices first.

Exemplu

curl -X DELETE https://api.e-bon.ro/api/v1/org/locations/loc_warehouse \
  -H "Authorization: Bearer <portal-jwt>"

GET /api/v1/org/settings/notifications

Returnează lista de abonați la notificări a organizației — adresele de email care primesc notificări de sistem, și categoriile pentru care fiecare abonat este înscris. Sunt suportați până la 20 de abonați.

Autentificare: JWT din Portal, rol Owner sau Admin

Pentru compatibilitate retroactivă, dacă organizația ta mai are adrese de email de notificare dintr-un format vechi, acestea sunt returnate ca abonați înscriși în toate categoriile. Apelează PATCH ca să migrezi explicit la noul model de abonați.

Răspuns 200

{
  "subscribers": [
    {
      "email": "owner@acme.example",
      "categories": ["reports", "billing"]
    },
    {
      "email": "ops@acme.example",
      "categories": ["alerts", "device_events", "analytics"]
    }
  ]
}

Cele cinci valori valide pentru categorii sunt:

CategorieNotificări acoperite
reportsRapoarte X/Z și rapoarte fiscale lunare.
alertsAlerte operaționale.
billingFacturi, schimbări de plan, evenimente de plată.
device_eventsEvenimente de dispozitiv online / offline / eroare.
analyticsSumare periodice de analiză.

Erori

  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.
  • NOT_FOUND (404) — organizația nu există.

Exemplu

curl https://api.e-bon.ro/api/v1/org/settings/notifications \
  -H "Authorization: Bearer <portal-jwt>"

PATCH /api/v1/org/settings/notifications

Înlocuiește lista de abonați la notificări a organizației. Corpul este lista completă — trimiterea unui tablou gol șterge toți abonații. Nu există un endpoint per-abonat de adăugare/eliminare; citește lista curentă, modific-o pe partea de client, apoi scrie-o înapoi.

Autentificare: JWT din Portal, rol Owner sau Admin

Corpul cererii

CâmpTipObligatoriuNote
subscribersobjectda0–20 intrări. Lista completă o înlocuiește pe cea anterioară.
subscribers[].emailstringdaTrebuie să fie o adresă de email validă.
subscribers[].categoriesstringdaCel puțin o intrare. Fiecare valoare trebuie să fie una dintre cele cinci categorii de mai sus.

Răspuns 200

{
  "subscribers": [
    { "email": "owner@acme.example", "categories": ["reports", "billing"] }
  ]
}

Erori

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea (email invalid, categorie necunoscută, mai mult de 20 de abonați, categories gol).
  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.
  • NOT_FOUND (404) — organizația nu există.

Exemplu

curl -X PATCH https://api.e-bon.ro/api/v1/org/settings/notifications \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "subscribers": [
      { "email": "owner@acme.example", "categories": ["reports", "billing"] },
      { "email": "ops@acme.example",   "categories": ["alerts", "device_events"] }
    ]
  }'

Vezi și

  • API Utilizatori — endpoint-urile de profil, doar JWT (/api/v1/users/me).
  • Autentificare — fluxul de login JWT din Portal și catalogul permisiunilor de cheie API.
  • Prezentare API — URL de bază, plic de eroare, limite de rată, paginare, catalog complet de coduri de eroare HTTP.
  • Portal › Locații — interfața UI pentru gestionarea locațiilor.
  • Portal › Organizație — interfața UI pentru editarea profilului organizației, a adresei de facturare și a abonaților la notificări.