openapi: 3.1.0
info:
  title: SmartBill API
  version: 1.0.0
  x-last-updated: '2026-08-21'
  contact:
    name: SmartBill API Support
    url: https://api.smartbill.ro
    email: api@smartbill.ro
  description: |-
    ## Introducere

    SmartBill API este un API REST pentru integrarea platformei SmartBill Cloud cu orice sistem extern: magazin online, ERP sau CRM. Endpoint-urile sunt organizate pe resurse (facturi, proforme, etc.), accepta JSON si returneaza coduri HTTP standard.

    ***Ultima actualizare: 17 august 2026***

    **Cu SmartBill API poti:**

    - sa emiti, sa stornezi, sa anulezi si sa stergi documente
    - sa emiti incasari si sa verifici statusul platii
    - sa interoghezi stocurile
    - sa trimiti documente pe email clientilor
    - sa interoghezi configurarile firmei (cote TVA, serii de documente)

    **Versiuni API**

    Alege **V1** pentru facturare si operatiuni curente. Alege **V3** pentru functii noi.

    | API | Scop | Base URL |
    |-----|------|----------|
    | **V1** | Facturare si operatiuni curente | `https://ws.smartbill.ro/SBORO/api` |
    | **V3** | Functii noi | `https://ws.smartbill.ro/SBORO/api/v3` |

    ## Integrare asistata de AI ✨

    Poti da documentatia API direct unui asistent AI - Claude, ChatGPT - si sa iti genereze cod de integrare, sa explice campuri sau sa te ajute cu erorile.

    **Descarca spec-ul OpenAPI**

    Descarca documentatia OpenAPI in format YAML sau JSON si ataseaz-o direct in orice asistent AI.

    **Prompt de context pentru AI**

    Copiaza promptul de mai jos si adauga-l inaintea intrebarii tale, impreuna cu fisierul spec atasat. Asta va ajuta AI-ul cu contextul de care are nevoie.

    ```text
    Ma ajuti sa integrez SmartBill API. Atasez spec-ul OpenAPI complet. Inainte sa-l citesti, iata context critic care nu se vede din schema:

    Alege API-ul corect: foloseste V1 pentru facturare si operatiuni curente. Foloseste V3 pentru functionalitatile noi documentate in spec. V1 foloseste Basic Auth cu email + apiToken. V3 foloseste Bearer token si include CIF-ul companiei in URL.

    Raspuns V1: campul errorText este sursa de adevar pentru cauza erorii - daca e gol apelul a reusit, daca e completat contine mesajul de eroare. Codul HTTP este semnificativ, dar nu acoperitor: citeste intotdeauna errorText, nu doar statusul.

    Erori V3: raspunsurile de eroare folosesc formatul cu errors[], code, message si docUrl. Pentru logica de integrare bazeaza-te pe statusul HTTP si pe code, nu doar pe textul mesajului.

    Typo la numele campului in V1: un camp cu nume necunoscut nu este ignorat. Cererea intoarce HTTP 400 cu un corp JSON de forma {"type": "invalid_request_error", "errors": [{"code": "json_mapping_error", "param": "<camp>"}]}, fara errorText. Citeste errors[].param ca sa afli exact ce camp e gresit. Aceeasi forma apare cand o valoare are alt tip decat cel asteptat si cand JSON-ul e invalid sintactic.

    Stringuri dependente de cont: seriesName, taxName si measuringUnitName trebuie sa coincida exact cu valorile configurate in contul SmartBill Cloud al utilizatorului. Nu inventa aceste valori; cere-le utilizatorului sau citeste-le din endpointurile/configurarile disponibile.

    Pret si TVA: preturile produselor in V1 sunt implicit FARA TVA (isTaxIncluded: false). Seteaza isTaxIncluded: true doar daca pretul include deja TVA.

    Rate limiting V1: 30 apeluri la 10 secunde per token. La depasire, accesul este blocat timp de 10 minute. Urmareste X-RateLimit-Limit, X-RateLimit-Remaining si X-RateLimit-Reset.

    Rate limiting V3: limitele sunt separate pentru citire si scriere si includ limita zilnica. Cererile se cumuleaza pe utilizator + companie, inclusiv cand sunt folosite mai multe token-uri sau aplicatii. La 429 foloseste Retry-After si header-ele X-RateLimit-* / X-RateLimit-Daily-* pentru retry si throttling. Nu face retry imediat.

    ```

    **Cu ce sa incepi**

    - *Genereaza-mi cod Python care emite o factura catre un client persoana juridica*
    - *Ce campuri sunt obligatorii la emiterea unei facturi?*
    - *Cum stornez o factura emisa gresit?*
    - *Ajuta-ma sa inteleg eroarea: Produsul Produs Test nu are codul specificat.*

    ## Quickstart

    Emite prima ta factura in 3 pasi simpli. Ai nevoie de un cont [SmartBill Cloud](https://cloud.smartbill.ro) activ.

    > 💡 SmartBill API are 2 versiuni:
    >
    > - **V1** - facturare, incasari, stocuri, configurari
    > - **V3** - gestiuni, produse, clienti, furnizori, NIR-uri
    >
    > Quickstart-ul foloseste V1. Pentru V3 vezi [Autentificare V3](#api-1/description/autentificare-v3).

    **Pasul 1. Creeaza o serie de facturi**

    Seriile de documente se configureaza din interfata SmartBill. Mergi in pagina [Serii](https://cloud.smartbill.ro/core/configurare/serii/) si creeaza o serie noua de facturi. Noteaza numele seriei - il vei folosi la pasul 3.

    **Pasul 2. Preia tokenul API V1**

    Tokenul API V1 este generat automat la crearea contului SmartBill. Mergi in pagina [Integrari](https://cloud.smartbill.ro/core/integrari/), la sectiunea **API** si copiaza valorile **Email**, **Token** si **CIF**. Le vei folosi la pasul urmator.

    **Pasul 3. Emite factura**

    Inlocuieste `EMAIL`, `TOKEN`, `CIF_FIRMA` (CIF-ul contului tau SmartBill) si seria facturii cu valoarea de la pasul 1:

    ```bash
    curl -X POST https://ws.smartbill.ro/SBORO/api/invoice/v2 \
      -u "EMAIL:TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "companyVatCode": "CIF_FIRMA",
        "client": { "name": "Client Test SRL", "country": "Romania" },
        "seriesName": "SERIA_FACTURII",
        "products": [{
          "name": "Produs Test",
          "code": "TEST01",
          "quantity": 1,
          "price": 100,
          "measuringUnitName": "buc",
          "taxName": "Normala",
          "taxPercentage": 21
        }]
      }'
    ```

    Raspuns:

    ```json
    {
      "errorText": "",
      "message": "",
      "number": "3593",
      "series": "SERIA_FACTURII",
      "url": "",
      "documentUrl": "https://cloud.smartbill.ro/documente/editare/factura/20363/",
      "documentId": 20363,
      "documentViewUrl": "https://cloud.smartbill.ro/documente/extern/pf/factura/f6a9a7d3...?srvid=2"
    }
    ```

    Daca `errorText` e gol, factura a fost emisa cu succes. Pentru toate optiunile (facturi din proforma, discount-uri, link de plata, etc.) si detaliile raspunsului, vezi [Facturi](#api-1/tag/facturi).

    ## Autentificare V1

    API-ul V1 foloseste **Basic Authentication** standard HTTP. Trimiti credentialele in headerul `Authorization`, sub forma `email:token` codificate base64.

    Credentialele le gasesti in pagina [Integrari](https://cloud.smartbill.ro/core/integrari/), sectiunea API.

    **Exemplu**

    ```bash
    curl -X POST https://ws.smartbill.ro/SBORO/api/invoice/v2 \
      -u "EMAIL:TOKEN" \
      -H "Content-Type: application/json" \
      -d '{ ... }'
    ```

    ## Autentificare V3

    API-ul V3 foloseste **Bearer tokens**. Trimiti tokenul in headerul `Authorization: Bearer <token>`. Tokenul se genereaza din pagina [Integrari](https://cloud.smartbill.ro/core/integrari/).

    URL-urile V3 includ CIF-ul companiei: `.../v3/companies/{cif}/resursa`. Inlocuieste `{cif}` cu CIF-ul tau la fiecare request.

    Fiecare token apartine unui singur utilizator si unei singure firme.

    **Exemplu**

    ```bash
    curl -H "Authorization: Bearer <token>" \
      https://ws.smartbill.ro/SBORO/api/v3/companies/CIF_FIRMA/clients
    ```

    ## Raspunsuri

    Toate raspunsurile sunt in format **JSON**, dar structura difera intre V1 si V3.

    **V1** - la succes primesti HTTP 200 cu `errorText` gol si campurile documentului emis. Erorile vin cu coduri HTTP specifice (400, 401 etc.) si `errorText` completat.

    ```json
    {
      "errorText": "",
      "message": "",
      "number": "3593",
      "series": "SERIA_FACTURII",
      "url": "",
      "documentUrl": "https://cloud.smartbill.ro/documente/editare/factura/20363/",
      "documentId": 20363,
      "documentViewUrl": "https://cloud.smartbill.ro/documente/extern/pf/factura/f6a9a7d3...?srvid=2"
    }
    ```

    | Camp | Continut |
    |------|----------|
    | `errorText` | Gol la succes. Daca e completat, contine cauza erorii. |
    | `message` | Mesaj auxiliar, de obicei gol. |
    | `number` + `series` | Identificatorul documentului (ex: `fac 3593`). |
    | `url` | Link de plata, populat doar daca ai trimis `paymentUrl: "Generate URL"`. |
    | `documentUrl` | Link de editare in SmartBill Cloud (necesita autentificare). |
    | `documentId` | ID-ul documentului in SmartBill Cloud. Inclus in `documentUrl`. `-1` la eroare. |
    | `documentViewUrl` | Link public catre PDF - il trimiti clientului final fara sa necesite autentificare. |

    **V3** - structura raspunsului depinde de tipul interogarii:

    | Tip interogare | Structura raspuns | Fara rezultate | Exemplu |
    |---|---|---|---|
    | Lista (`/warehouses`) | `items[]` + obiect `pagination` | `items: []`, `pagination.next/previous: null` - nu primesti 404 | `{ "items": [...], "pagination": { "next": "...", "previous": null } }` |
    | Dupa ID (`/warehouses/{id}`) | obiect direct, fara `items` | 404 | `{ "id": "...", "name": "..." }` |

    **Id-urile V3** sunt stabile in timp: le poti salva la tine si le poti folosi oricand ulterior, ca sa ceri inregistrarea prin `GET .../{id}` sau drept cursor `after` / `before` la paginare. Prefixul spune tipul inregistrarii:

    | Prefix | Resursa |
    |---|---|
    | `cus_` | clienti |
    | `sup_` | furnizori |
    | `ware_` | gestiuni |
    | `prod_` | produse si servicii |

    Un id folosit pe alta resursa decat cea a prefixului intoarce `400` cu `malformed_id`.

    ## Reguli generale de format

    - **Codificare**: corpul cererii se trimite in **UTF-8**.
    - **Booleeni**: campurile de tip boolean accepta si `1` / `0`, nu doar `true` / `false`.
    - **Procente**: valorile procentuale se trimit ca numar, fara simbolul `%`. `taxPercentage: 21` merge; `taxPercentage: "21%"` intoarce `400`.
    - **Caractere speciale in JSON**: ghilimelele si backslash-ul din texte trebuie escapate (`\"` si `\\`), altfel corpul cererii nu e JSON valid si primesti `400`.

    ## Paginare

    Paginarea se aplica doar la **API V3**. API V1 nu suporta paginare.

    Endpoint-urile de listare V3 accepta urmatorii query params:

    | Parametru | Tip | Min | Max | Implicit | Descriere |
    |-----------|-----|-----|-----|----------|-----------|
    | `limit` | number | 1 | 100 | 20 | Numar maxim de rezultate |
    | `after` | string | - | - | - | Cursor: id-ul dupa care se continua (exclusiv cu `before`) |
    | `before` | string | - | - | - | Cursor: id-ul inainte de care se continua (exclusiv cu `after`) |

    **Exemplu lista paginata**

    ```bash
    curl -X GET "https://ws.smartbill.ro/SBORO/api/v3/companies/CIF_FIRMA/warehouses?limit=5&after=ware_019f17cddf1272d59f06892d5b760d0b" \
      -H "Authorization: Bearer <token>"
    ```

    **Urmarirea cursorului**

    `pagination.next` si `pagination.previous` sunt URL-uri complete si pastreaza filtrele cererii initiale. Le apelezi ca atare, fara sa readaugi `name`, `code` sau `vatCode`.

    Cand nu mai exista pagina in directia respectiva, campul e `null`. Asta e valabil si cand ultima pagina s-a umplut exact la `limit`, deci `next: null` inseamna sigur ca s-a terminat - nu mai ai de ce sa ceri o pagina in plus ca sa verifici.

    **Erori de paginare**

    | Situatie | `code` | HTTP |
    |----------|--------|------|
    | `limit` in afara intervalului (0 sau 101) | `invalid_field_value` | 400 |
    | `limit` nu e numar | `invalid_field_type` | 400 |
    | `before` si `after` folosite impreuna | `invalid_field_value` | 400 |
    | cursor cu prefix gresit | `malformed_id` | 400 |
    | cursor cu format invalid | `malformed_id` | 400 |

    ## Erori

    SmartBill API foloseste coduri HTTP standard. Formatul corpului de eroare difera intre V1 si V3.

    ### Erori API V1

    Raspunsul de eroare V1 contine mesajul in campul `errorText`.

    | Cod HTTP | Explicatie | Cand apare |
    |----------|------------|------------|
    | 400 | Request invalid | JSON malformat, nume de camp necunoscut, valoare de alt tip sau validare de business picata |
    | 401 | Neautentificat | Credentiale sau token gresit |
    | 403 | Interzis | Token fara permisiuni pe resursa |
    | 404 | Nu exista | Resursa cu ID/CIF/seria specificata nu exista |
    | 405 | Metoda nepermisa | Verbul HTTP nu e acceptat pe endpoint, de exemplu `GET` pe `/invoice/v2`. Raspunsul include headerul `Allow` cu verbele acceptate |
    | 415 | Tip de continut nesuportat | `Content-Type` lipseste sau are alta valoare decat `application/json` |
    | 422 | Date invalide (validare business) | Citeste `errorText` pentru cauza |
    | 429 | Rate limit depasit | Prea multe apeluri. Urmareste header-ele de rate limit |
    | 500 | Eroare server | Reincearca cu backoff |

    **Raspunsurile de eroare vin in doua forme.** Nu toate au `errorText`:

    - **Validare de business** - forma clasica V1, cu `errorText` completat: serie inexistenta, lista
      de produse goala, cota TVA inexistenta, drepturi lipsa. Codurile tipice sunt `400`, `401` si `422`.
    - **Cerere invalida** - cererea e respinsa inainte de logica de facturare si raspunsul **nu are
      `errorText`**. Corpul are alta forma:

    ```json
    {
      "status": 400,
      "type": "invalid_request_error",
      "instance": "/SBORO/api/invoice/v2",
      "errors": [
        {
          "code": "json_mapping_error",
          "message": "Unrecognized property: zzz.",
          "docUrl": "https://api.smartbill.ro/#v3-error-invalid_request_error",
          "param": "zzz"
        }
      ]
    }
    ```

    Valorile lui `code`:

    | `code` | Cand apare | Exemplu de `message` |
    |--------|------------|----------------------|
    | `json_mapping_error` | Nume de camp necunoscut | `Unrecognized property: zzz.` |
    | `json_mapping_error` | Valoare de alt tip decat cel asteptat | `Could not map property: products[0].quantity.` |
    | `json_parse_error` | JSON invalid sintactic | `Error parsing JSON request input.` |
    | `invalid_accept_header` | Header `Accept` pe care endpointul nu il poate servi. Raspunsul e `406` | `The requested resource is not available in the requested format.` |
    | `method_not_allowed` | Verb HTTP nepermis pe endpoint. Raspunsul e `405` si include headerul `Allow` | - |

    Aceeasi forma o au si raspunsurile `405` si `415`. Campul `param` numeste exact campul
    problematic, inclusiv in sub-obiecte si in liste: `estimate.paymentUrl`, `products[0].quantity`.

    In practica: citeste `errorText` daca exista, altfel `errors[].message` si `errors[].param`.

    **`errorText` poate contine HTML.** Erorile de descarcare de gestiune vin cu marcaje in text:

    | Eroare | Ce marcaje contine |
    |--------|--------------------|
    | `Nu ai facut nicio achizitie pentru produsul <nume>.` | `<br/>` inainte de sugestie |
    | `Cantitate stoc insuficienta la ... pentru produsul ...` | `<b>` in jurul documentului, datei si numelui de produs |
    | `Unitatea de masura <um> a produsului <nume> nu are factor de conversie setat.` | un `<div id="moreErrorDetails" style="display:none">` cu cateva paragrafe de text de ajutor |

    Nu afisa `errorText` ca text simplu, dar nu-l randa nici ca HTML fara sa-l cureti. Cel mai simplu
    e sa iei doar prima propozitie, pana la primul `<`: acolo sta cauza, restul e ajutor pentru
    interfata SmartBill Cloud.

    **Format eroare V1**

    ```json
    {
      "errorText": "Seria nu a fost gasita! Folositi o serie creata in contul de cloud.",
      "message": "",
      "number": "",
      "series": "",
      "documentUrl": "",
      "documentId": -1,
      "documentViewUrl": ""
    }
    ```

    > **Atentie:** un camp scris gresit in payload (ex. `nume` in loc de `name`) intoarce **500** cu raspuns HTML, nu JSON. Nu e o eroare de server reala - verifica numele campurilor din schema.

    Erorile de mai jos sunt comune tuturor endpoint-urilor V1 (factura, proforma, bon fiscal etc.) si tin de apelant, nu de tipul documentului.

    <details>
    <summary><strong>Autentificare</strong></summary>

    <table>
      <thead>
        <tr>
          <th>Situatie</th>
          <th>Eroare</th>
          <th>Sugestie</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Email sau token gresit</td>
          <td><code>Autentificare esuata. Va rugam verificati datele si incercati din nou.</code></td>
          <td>Verifica `email`-ul si tokenul API V1. Daca par corecte, verifica mediul - un token de test folosit pe productie esueaza.</td>
        </tr>
        <tr>
          <td><code>companyVatCode</code> lipseste</td>
          <td><code>Firma la care incercati sa va conectati nu mai este disponibila in Cloud.</code></td>
          <td>Adauga `companyVatCode` cu CIF-ul exact al firmei active din contul Cloud.</td>
        </tr>
        <tr>
          <td><code>companyVatCode</code> fara drepturi</td>
          <td><code>Firma la care incercati sa va conectati nu este disponibila pentru acest utilizator.</code></td>
          <td>CIF-ul exista, dar utilizatorul autentificat nu are drepturi pe acea firma. Foloseste un CIF la care ai acces sau cere drepturi administratorului.</td>
        </tr>
        <tr>
          <td><code>companyVatCode</code> = <code>null</code></td>
          <td><code>Internal Server Error!</code></td>
          <td>Trimiti `null` ca valoare JSON in loc de CIF. Trimite CIF-ul ca string. Caz limita.</td>
        </tr>
      </tbody>
    </table>

    </details>

    <details>
    <summary><strong>Autorizare</strong></summary>

    <table>
      <thead>
        <tr>
          <th>Situatie</th>
          <th>Eroare</th>
          <th>Sugestie</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Drept de adaugare facturi</td>
          <td><code>Nu aveti dreptul de a adauga facturi</code></td>
          <td>Utilizatorul nu are dreptul de a adauga facturi. Drepturile se modifica din meniul <a href="https://cloud.smartbill.ro/core/utilizatori/">Utilizatori</a> in SmartBill Cloud. Cere acces administratorului contului.</td>
        </tr>
        <tr>
          <td>Drept pe seria selectata</td>
          <td><code>Nu aveti dreptul de a adauga facturi pe seria selectata</code></td>
          <td>Utilizatorul nu are drept pe aceasta serie. Drepturile pe serii se modifica din meniul <a href="https://cloud.smartbill.ro/core/utilizatori/">Utilizatori</a> in SmartBill Cloud. Cere acces administratorului contului.</td>
        </tr>
      </tbody>
    </table>

    </details>

    ### Erori API V3

    API-ul V3 returneaza erorile in format JSON, folosind o structura unitara. Campul `errors` poate contine una sau mai multe erori intr-un singur raspuns.

    **Format standard**

    ```http
    HTTP/1.1 400 Bad Request
    Content-Type: application/json
    ```

    ```json
    {
      "status": 400,
      "type": "validation_error",
      "instance": "/api/v3/clients",
      "errors": [
        {
          "code": "missing_required_field",
          "message": "must not be blank",
          "docUrl": "https://api.smartbill.ro/#v3-error-validation_error",
          "param": "name"
        }
      ]
    }
    ```

    | Camp | Tip | Descriere |
    |---|---|---|
    | `status` | integer | Codul HTTP al raspunsului. |
    | `type` | string | Categoria generala a erorii. |
    | `instance` | string | URI-ul cererii care a produs eroarea. |
    | `errors` | array | Lista erorilor identificate. Contine unul sau mai multe elemente. |
    | `errors[].code` | string | Codul stabil folosit pentru tratarea programatica a erorii. |
    | `errors[].message` | string | Mesaj explicativ destinat diagnosticarii sau afisarii. |
    | `errors[].docUrl` | string | URL-ul documentatiei pentru eroarea respectiva. |
    | `errors[].param` | string, optional | Campul sau parametrul care a produs eroarea. |

    Aplicatia client trebuie sa foloseasca `type` si `errors[].code` pentru luarea deciziilor. Textul din `message` nu trebuie folosit ca identificator stabil.

    `docUrl` duce mereu la categoria de eroare, nu la codul individual. Forma este `https://api.smartbill.ro/#v3-error-{type}`, de exemplu `https://api.smartbill.ro/#v3-error-authentication_error`. Nu exista un URL per `code`: toate erorile cu acelasi `type` primesc acelasi `docUrl`. Pentru a distinge cazul concret, foloseste `errors[].code`.

    **Tipurile de eroare**

    | `type` | Semnificatie | Coduri HTTP | Link intern |
    |---|---|---|---|
    | `authentication_error` | Cheia API nu poate fi autentificata. | `401` | [vezi tabelul](#v3-error-authentication_error) |
    | `authorization_error` | Cheia API este autentificata, dar operatia nu este permisa. | `403` | [vezi tabelul](#v3-error-authorization_error) |
    | `invalid_request_error` | Cererea, resursa sau reprezentarea HTTP este incorecta. | `400`, `404`, `405`, `406`, `415`, `429` | [vezi tabelul](#v3-error-invalid_request_error) |
    | `validation_error` | Datele din cerere nu respecta regulile de validare. | `400` | [vezi tabelul](#v3-error-validation_error) |
    | `api_error` | API-ul nu poate procesa cererea dintr-o cauza interna sau temporara. | `500`, `503` | [vezi tabelul](#v3-error-api_error) |

    <span id="v3-error-authentication_error"></span>

    **authentication_error - Erori de autentificare**

    Toate erorile din aceasta categorie au `type: authentication_error` si returneaza `401 Unauthorized`.

    | `code` | Descriere | Actiunea recomandata |
    |---|---|---|
    | `missing_authorization` | Header-ul `Authorization` lipseste sau are o valoare goala. | Trimite header-ul `Authorization` folosind schema Bearer. |
    | `invalid_authorization_format` | Header-ul `Authorization` nu respecta formatul acceptat. | Verifica schema Bearer, prezenta tokenului si absenta valorilor suplimentare. |
    | `invalid_api_key` | Cheia API nu poate fi validata. | Verifica cheia si inlocuieste-o daca nu mai este valida. Nu retrimite automat cererea cu aceeasi cheie. |
    | `wrong_environment` | Cheia API apartine unui alt mediu decat cel al rutei apelate. | Foloseste cheia API si URL-ul corespunzatoare aceluiasi mediu. |

    Formatul corect al header-ului de autentificare este:

    ```http
    Authorization: Bearer <token>
    ```

    Pe V3, un token `sb_test_` folosit pe productie sau un token de productie folosit pe test returneaza `401`, chiar daca tokenul este valid pentru mediul lui.

    <span id="v3-error-authorization_error"></span>

    **authorization_error - Erori de autorizare**

    Toate erorile din aceasta categorie au `type: authorization_error` si returneaza `403 Forbidden`.

    | `code` | Descriere | Actiunea recomandata |
    |---|---|---|
    | `insufficient_permissions` | Utilizatorul asociat cheii API nu are permisiunea necesara. | Foloseste un utilizator autorizat sau acorda permisiunea necesara. |
    | `subscription_expired` | Abonamentul companiei a expirat. | Reinnoieste abonamentul inainte de a retrimite cererea. |
    | `subscription_limit_exceeded` | A fost depasita limita inclusa in abonamentul companiei. | Redu utilizarea sau modifica abonamentul. |
    | `subscription_not_found` | Compania nu are un abonament asociat. | Activeaza un abonament inainte de a retrimite cererea. |
    | `subscription_not_valid` | Abonamentul curent nu permite operatia API solicitata. | Foloseste un abonament compatibil cu operatia. |

    Erorile de autorizare nu trebuie retrimise automat. Aceeasi cerere va continua sa primeasca `403 Forbidden` pana la modificarea permisiunilor sau a abonamentului.

    <span id="v3-error-invalid_request_error"></span>

    **invalid_request_error - Erori ale cererii**

    Erorile din aceasta categorie au `type: invalid_request_error` si indica o problema cu ruta, metoda, headerele, parametrii, corpul JSON sau limita de trafic.

    | `code` | Cod HTTP | Descriere | Actiunea recomandata |
    |---|---:|---|---|
    | `company_not_found` | `404` | Compania identificata prin codul fiscal nu a fost gasita. | Verifica codul fiscal si accesul cheii API la companie. |
    | `supplier_not_found` | `404` | Furnizorul identificat prin ID nu a fost gasit. | Verifica ID-ul sau actualizeaza lista furnizorilor. |
    | `client_not_found` | `404` | Clientul identificat prin ID nu a fost gasit. | Verifica ID-ul sau actualizeaza lista clientilor. |
    | `product_not_found` | `404` | Produsul identificat prin ID nu a fost gasit. | Verifica ID-ul sau actualizeaza lista produselor. |
    | `warehouse_not_found` | `404` | Gestiunea identificata prin ID nu a fost gasita. | Verifica ID-ul sau actualizeaza lista gestiunilor. |
    | `resource_not_found` | `404` | Ruta sau resursa solicitata nu exista. | Verifica versiunea API, URL-ul, calea si ID-ul resursei. |
    | `method_not_allowed` | `405` | Metoda HTTP nu este permisa pentru ruta solicitata. | Foloseste metoda indicata in documentatia rutei. |
    | `invalid_accept_header` | `406` | Header-ul `Accept` nu solicita formatul returnat de API. | Foloseste `Accept: application/json`. |
    | `invalid_content_type` | `415` | Header-ul `Content-Type` nu declara formatul acceptat de API. | Pentru cererile care au corp, foloseste `Content-Type: application/json`. |
    | `bad_request` | `400` | Cererea contine parametri invalizi sau date lipsa. | Verifica parametrii, headerele si corpul cererii. |
    | `json_parse_error` | `400` | Corpul cererii nu este un document JSON valid. | Verifica ghilimelele, virgulele, parantezele, caracterele escape si inchiderea sirurilor. |
    | `json_mapping_error` | `400` | JSON-ul este valid sintactic, dar structura sau valorile nu corespund modelului acceptat. | Corecteaza numele, tipul sau structura campului indicat prin `param`. |
    | `missing_vat_code` | `400` | Codul fiscal necesar operatiei lipseste sau are o valoare goala. | Furnizeaza un cod fiscal valid. |
    | `malformed_id` | `400` | ID-ul resursei lipseste sau nu respecta formatul solicitat. | Foloseste ID-urile returnate de API fara a le modifica structura. |
    | `rate_limit_exceeded` | `429` | Aplicatia client a depasit limita de cereri permisa. | Respecta `Retry-After`, foloseste temporizare exponentiala si adauga o variatie aleatorie intre reincercari. |

    API-ul accepta si returneaza exclusiv `application/json`. Pentru cererile care au corp, foloseste:

    ```http
    Accept: application/json
    Content-Type: application/json
    ```

    Pentru `json_mapping_error`, campul `param` poate contine calea completa a proprietatii afectate:

    ```json
    {
      "code": "json_mapping_error",
      "message": "Could not parse property: payment.isCash.",
      "docUrl": "https://api.smartbill.ro/#v3-error-invalid_request_error",
      "param": "payment.isCash"
    }
    ```

    <span id="v3-error-validation_error"></span>

    **validation_error - Erori de validare**

    Toate erorile din aceasta categorie au `type: validation_error` si returneaza `400 Bad Request`.

    | `code` | Descriere | Actiunea recomandata |
    |---|---|---|
    | `invalid_field_type` | Valoarea unui camp sau parametru nu are tipul solicitat. | Trimite valoarea folosind tipul corect. |
    | `invalid_field_value` | Valoarea are tipul corect, dar nu respecta regulile acceptate. | Corecteaza valoarea indicata prin `param`. |
    | `invalid_enum_value` | Valoarea nu apartine listei de optiuni acceptate. | Foloseste una dintre valorile documentate pentru camp. |
    | `missing_required_field` | Un camp obligatoriu lipseste, este gol sau are valoarea `null`. | Furnizeaza campul indicat prin `param`. |
    | `invalid_field_format` | Valoarea nu respecta formatul solicitat. | Corecteaza formatul campului, de exemplu formatul unei date sau adrese de e-mail. |
    | `dependency_not_available` | Valoarea solicitata depinde de o optiune indisponibila in contextul cererii. | Verifica datele asociate si conditiile documentate pentru ruta. |

    Un raspuns poate contine mai multe erori, cate una pentru fiecare camp invalid:

    ```json
    {
      "status": 400,
      "type": "validation_error",
      "instance": "/api/v3/resource",
      "errors": [
        {
          "code": "missing_required_field",
          "message": "must not be blank",
          "docUrl": "https://api.smartbill.ro/#v3-error-validation_error",
          "param": "name"
        },
        {
          "code": "invalid_field_format",
          "message": "must be a well-formed email address",
          "docUrl": "https://api.smartbill.ro/#v3-error-validation_error",
          "param": "email"
        }
      ]
    }
    ```

    Aplicatia client trebuie sa proceseze intreaga lista `errors`, nu doar primul element.

    <span id="v3-error-api_error"></span>

    **api_error - Erori ale API-ului**

    Erorile din aceasta categorie au `type: api_error` si indica o cauza interna sau temporara.

    | `code` | Cod HTTP | Descriere | Actiunea recomandata |
    |---|---:|---|---|
    | `maintenance_in_progress` | `503` | API-ul este temporar indisponibil din cauza unei perioade de mentenanta. | Respecta `Retry-After` si amana cererile. |
    | `rate_limit_temporarily_unavailable` | `503` | Serviciul de evaluare a limitei de trafic este temporar indisponibil. | Respecta `Retry-After` si foloseste temporizare exponentiala. |
    | `query_timeout` | `503` | Operatia a depasit timpul maxim de executie. | Retrimite cererea dupa o secunda sau ajusteaza parametrii cererii. |
    | `internal_error` | `500` | API-ul a intampinat o eroare neasteptata. | Reincearca controlat numai daca operatia este idempotenta sau protejata impotriva duplicarii. |

    `rate_limit_temporarily_unavailable` indica faptul ca limita de trafic nu a putut fi evaluata temporar. Nu indica depasirea limitei de catre aplicatia client.

    Daca un `internal_error` persista, pastreaza valorile `instance` si `code` pentru comunicarea cu echipa de suport.

    **Tratarea erorilor in aplicatia client**

    | Cod HTTP | Reincercare recomandata | Actiune |
    |---:|---|---|
    | `400` | Nu | Corecteaza parametrii sau corpul cererii. |
    | `401` | Nu, cu aceeasi cheie API | Corecteaza sau inlocuieste cheia API. |
    | `403` | Nu | Corecteaza permisiunile sau abonamentul. |
    | `404` | Nu | Verifica ruta sau ID-ul resursei. |
    | `405` | Nu | Foloseste metoda HTTP corecta. |
    | `406` | Nu | Corecteaza header-ul `Accept`. |
    | `415` | Nu | Corecteaza header-ul `Content-Type`. |
    | `429` | Da | Respecta `Retry-After` si aplica temporizare exponentiala. |
    | `500` | Limitat | Reincearca numai operatiile idempotente sau protejate impotriva duplicarii. |
    | `503` | Da | Respecta `Retry-After` si aplica temporizare exponentiala. |

    In loguri, pastreaza codul HTTP, `type`, fiecare valoare `errors[].code`, `errors[].param` daca este prezent si `instance`. Nu scrie in log chei API, header-ul `Authorization`, tokenuri de acces sau date sensibile din cerere ori raspuns.

    ## Rate Limiting

    ### API V1

    In **API V1**, accesul este limitat la **30 de apeluri in 10 secunde** per token. In caz de abatere, accesul este blocat timp de **10 minute**.

    Raspunsurile serverului SmartBill includ headere care indica starea ferestrei curente de 10 secunde:

    | Header | Descriere |
    |--------|-----------|
    | `X-RateLimit-Limit` | Cate apeluri se pot face in fereastra de 10 secunde. Pentru V1 valoarea este `30`. |
    | `X-RateLimit-Remaining` | Numarul de apeluri ramase in fereastra curenta de 10 secunde. |
    | `X-RateLimit-Reset` | Unix timestamp cand incepe noua fereastra de 10 secunde. |

    ### API V3

    In **API V3**, rate limit-urile se aplica cererilor autentificate catre endpoint-urile publice si sunt calculate pentru utilizatorul si compania asociate cererii. Daca acelasi utilizator si aceeasi companie folosesc mai multe token-uri, servicii sau aplicatii, cererile se cumuleaza in aceleasi limite.

    Daca nu ai primit alte limite prin contract sau printr-o comunicare SmartBill, se aplica urmatoarele valori standard:

    | Categorie | Limita standard |
    |-----------|-----------------|
    | Citire (`GET`, `HEAD`) | 60 cereri la 10 secunde |
    | Scriere (`POST`, `PUT`, `PATCH`, `DELETE` si alte metode non-`GET`/non-`HEAD`) | 30 cereri la 10 secunde |
    | Total zilnic | 50.000 cereri pe zi |

    Limita zilnica se reseteaza, in mod standard, la miezul noptii conform fusului orar al Romaniei (`Europe/Bucharest`). Limitele pot fi diferite pentru anumite conturi sau companii, deci clientii API trebuie sa citeasca valorile efective din header-ele de raspuns.

    La depasirea limitei pe V3, primesti **429 Too Many Requests** cu headerul `Retry-After` care indica numarul minim de secunde de asteptat inainte de retry:

    ```json
    {
      "status": 429,
      "type": "invalid_request_error",
      "instance": "/api/v3/{vatCode}/...",
      "errors": [
        {
          "code": "rate_limit_exceeded",
          "message": "Rate limit exceeded. Please try again in 10 seconds.",
          "docUrl": "https://api.smartbill.ro/#v3-error-invalid_request_error"
        }
      ]
    }
    ```

    Mesajul de eroare este informativ si poate varia in functie de durata de asteptare. Integrarea trebuie sa se bazeze pe statusul HTTP `429`, pe `code: rate_limit_exceeded` si pe headerul `Retry-After`.

    Daca aplicatia continua sa trimita cereri dupa depasirea limitei, valoarea `Retry-After` poate creste progresiv. In configuratia standard, intervalele de penalizare pot creste pana la cateva minute: `5, 10, 20, 40, 80, 160, 300, 600` secunde. Aceste valori pot fi diferite pentru anumite conturi sau companii. Foloseste intotdeauna valoarea primita in headerul `Retry-After`.

    Raspunsurile API V3 pentru care a fost calculat rate limit-ul includ:

    | Header | Descriere |
    |--------|-----------|
    | `X-RateLimit-Limit` | Limita efectiva pentru fereastra scurta aplicabila cererii curente. Pentru `GET`/`HEAD` este limita de citire; pentru celelalte metode este limita de scriere. |
    | `X-RateLimit-Remaining` | Numarul de cereri ramase in fereastra scurta curenta. |
    | `X-RateLimit-Reset` | Unix timestamp, in secunde, cand se reseteaza fereastra scurta sau intervalul curent de asteptare. |
    | `X-RateLimit-Daily-Limit` | Limita zilnica efectiva. |
    | `X-RateLimit-Daily-Remaining` | Numarul de cereri ramase pana la resetarea limitei zilnice. |
    | `X-RateLimit-Daily-Reset` | Unix timestamp, in secunde, cand se reseteaza limita zilnica. |
    | `Retry-After` | Prezent pe raspunsurile pentru care clientul trebuie sa astepte inainte de retry, de exemplu `429 Too Many Requests` sau `503 Service Unavailable`. Valoarea este in secunde. |

    Daca limita zilnica a fost epuizata, API-ul raspunde tot cu **429 Too Many Requests**. In acest caz, `X-RateLimit-Daily-Remaining` va fi `0`, iar `X-RateLimit-Daily-Reset` indica momentul resetarii limitei zilnice.

    In cazuri rare, API-ul nu poate evalua temporar starea rate limit-ului. In aceasta situatie raspunsul este **503 Service Unavailable**, nu `429`, si include `Retry-After`.

    - Implementeaza retry cu backoff pentru raspunsurile `429 Too Many Requests` si pentru raspunsurile temporare `503 Service Unavailable` care includ `Retry-After`
    - Asteapta cel putin numarul de secunde indicat de `Retry-After` inainte de retry
    - Monitorizeaza `X-RateLimit-Remaining` si `X-RateLimit-Daily-Remaining`; cand valorile se apropie de `0`, redu temporar ritmul cererilor
    - Foloseste paginare si batch processing unde e posibil (ex: nu crea facturi una cate una in bucle rapide)
servers:
- url: https://ws.smartbill.ro/SBORO/api
  description: Productie
security:
- basicAuth: []
x-tagGroups:
- name: Endpoints V1
  tags:
  - Facturi
  - Proforme
  - Incasari
  - Stocuri
  - Email
  - Configurari
- name: Endpoints V3 (Beta)
  tags:
  - NIR-uri (in curand)
  - Produse
  - Clienti
  - Furnizori
  - Gestiuni
tags:
- name: Clienti
  description: |
    Interogare si gestionare clienti.

    > 🔐 **Autentificare**: Bearer token - vezi sectiunea [Autentificare V3](#api-1/description/autentificare-v3).

- name: Furnizori
  description: |
    Interogare si gestionare furnizori.

    > 🔐 **Autentificare**: Bearer token - vezi sectiunea [Autentificare V3](#api-1/description/autentificare-v3).

- name: Gestiuni
  description: |
    Interogare gestiuni si depozite.

    > 🔐 **Autentificare**: Bearer token - vezi sectiunea [Autentificare V3](#api-1/description/autentificare-v3).

- name: Produse
  description: |
    Interogare catalog produse si servicii.

    > 🔐 **Autentificare**: Bearer token - vezi sectiunea [Autentificare V3](#api-1/description/autentificare-v3).

- name: NIR-uri (in curand)
  description: |
    Creare si gestionare Note de Intrare Receptie.

    > 🔐 **Autentificare**: Bearer token - vezi sectiunea [Autentificare V3](#api-1/description/autentificare-v3).

    > 🚧 **In dezvoltare** - Endpoint-urile vor fi adaugate pe masura ce sunt finalizate.

- name: Facturi
  description: |
    Aceasta sectiune acopera ciclul de viata al unei facturi: emitere, stornare, anulare, restaurare si stergere.

    Operatii disponibile:
    - Emitere factura simpla sau pe baza unei proforme
    - Emitere factura ciorna (draft)
    - Emitere factura cu link de plata, in valuta, cu descarcare de gestiune
    - Obtinere PDF factura
    - Verificare status incasare factura
    - Trimitere factura pe email
- name: Proforme
  description: |
    Operatiuni cu proforme/devize - creare, vizualizare PDF, anulare, stergere.

    Similar cu facturile, dar pentru documente de tip proforma.
- name: Incasari
  description: |
    Operatiuni de plata/incasare.

    **Tipuri de plata** - valorile se trimit in campul `type`:
    - Card
    - Card online
    - Chitanta
    - Bon (bon fiscal)
    - Ordin plata
    - CEC
    - Bilet ordin
    - Mandat postal
    - Extras de cont
    - Ramburs
    - Alta incasare

    Litera mare nu conteaza: `Ramburs`, `ramburs` si `RAMBURS` sunt tratate la fel. Spatiile in plus
    invalideaza valoarea - `Ramburs ` sau `Card  online` intorc `404` cu
    `Tipul documentului nu a fost gasit pe server!`.

    Doar `Chitanta` si `Bon` genereaza un document separat. Celelalte tipuri inregistreaza incasarea
    fara sa emita document, iar raspunsul vine fara `number` si `series`.
- name: Configurari
  description: |
    Date de configurare - serii, taxe, informatii despre firma.
- name: Stocuri
  description: |
    Operatiuni de stoc/inventar.
- name: Email
  description: |
    Trimitere documente prin email catre clienti.
paths:
  /invoice/v2:
    post:
      tags:
      - Facturi
      summary: Emitere factura
      operationId: createInvoiceV2
      security:
      - basicAuth: []
      description: |
        Emite o factura noua. Poti emite factura ca ciorna (draft), pe care o finalizezi ulterior din interfata SmartBill.

        **Ai primit o eroare la emiterea facturii?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `companyVatCode`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice emiterii de factura.

        <details>
        <summary><strong>Date document si serii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Serie inexistenta in cont</td>
              <td><code>Seria nu a fost gasita! Folositi o serie creata in contul de cloud.</code></td>
              <td>Seria trebuie definita in SmartBill Cloud. Trimite in `seriesName` seria facturii, exact cum e configurata in cont.</td>
            </tr>
            <tr>
              <td>Contul a atins numarul maxim de documente permis de pachetul de abonament</td>
              <td><code>Pentru acest pachet s-a emis numarul maxim de documente permis</code></td>
              <td>Limita vine din abonamentul contului SmartBill Cloud, nu din API, deci nu se ridica din integrare. Verifica pachetul in cont.</td>
            </tr>
            <tr>
              <td>Moneda inexistenta sau scrisa gresit</td>
              <td><code>Moneda nu a fost gasita pe server!</code></td>
              <td>Verifica moneda trimisa in `currency`. Valorile acceptate sunt listate in schema campului.</td>
            </tr>
            <tr>
              <td>Data documentului in format gresit</td>
              <td><code>Data documentului trebuie sa fie de forma yyyy-MM-dd.</code></td>
              <td>Trimite `issueDate` in format `yyyy-MM-dd`, de exemplu `2026-06-15`.</td>
            </tr>
            <tr>
              <td><code>sendEmail</code> fara adresa destinatar</td>
              <td><code>Trebuie specificata adresa de email a clientului.</code></td>
              <td>Cand `sendEmail` e `true`, completeaza adresa destinatarului in `email.to` sau in `client.email`.</td>
            </tr>
            <tr>
              <td><code>sendEmail</code> fara server de email</td>
              <td><code>Server-ul de email nu a fost configurat.</code></td>
              <td>Contul nu are un server de email configurat. Intra in SmartBill Cloud si configureaza-ti propriul server de email din <a href="https://cloud.smartbill.ro/core/configurare_mailuri/">Configurare > Email</a>.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Client</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Obiectul <code>client</code> lipseste</td>
              <td><code>tara trebuie specificata</code></td>
              <td>Trimite `client` cu cel putin `name` si `country`.</td>
            </tr>
            <tr>
              <td><code>client.name</code> gol sau <code>null</code></td>
              <td><code>Client invalid!</code></td>
              <td>Trimite un `client.name` valid (nu gol, nu `null`).</td>
            </tr>
            <tr>
              <td><code>client.country</code> lipseste</td>
              <td><code>tara trebuie specificata</code></td>
              <td>Completeaza `client.country`, ex. `Romania`.</td>
            </tr>
            <tr>
              <td>Client duplicat in nomenclator</td>
              <td><code>Clientul exista deja pe server</code></td>
              <td>Exista deja un client cu acelasi nume dar alt CIF. Sterge duplicatul din nomenclator.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Produse, TVA si discounturi</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Lista `products` goala</td>
              <td><code>invoiceProducts trebuie specificat si trebuie sa contina cel putin un element</code></td>
              <td>Trimite cel putin un produs in `products`.</td>
            </tr>
            <tr>
              <td><code>products[].name</code> lipsa</td>
              <td><code>name trebuie specificat pentru fiecare produs</code></td>
              <td>Trimite `name` la fiecare produs.</td>
            </tr>
            <tr>
              <td><code>products[].measuringUnitName</code> lipsa</td>
              <td><code>measuringUnitName trebuie specificat pentru fiecare produs</code></td>
              <td>Trimite `measuringUnitName` (case-sensitive, sa existe in cont).</td>
            </tr>
            <tr>
              <td>Cota TVA a produsului inexistenta</td>
              <td><code>Cota tva a produsului ... nu a fost gasita pe server!</code></td>
              <td>Foloseste o cota TVA existenta in cont.</td>
            </tr>
            <tr>
              <td>Produs fara cota TVA setata</td>
              <td><code>Trebuie sa setezi o cota tva pentru produsul ...</code></td>
              <td>Seteaza `taxPercentage` la fiecare produs.</td>
            </tr>
            <tr>
              <td>Document doar cu discount</td>
              <td><code>Nu poti sa emiti un document care contine doar un discount. Trebuie sa ai si produse / servicii adaugate.</code></td>
              <td>Adauga si produse, nu doar linie de discount.</td>
            </tr>
            <tr>
              <td>Discount procentual fara procent</td>
              <td><code>Trebuie sa introduceti valoarea procentului!</code></td>
              <td>Trimite `discountPercentage` pe linia de discount.</td>
            </tr>
            <tr>
              <td>Produs fara cod</td>
              <td><code>Produsul ... nu are codul specificat.</code></td>
              <td>Daca firma foloseste cod produs, trimite `code` la fiecare produs.</td>
            </tr>
            <tr>
              <td>Produs fara cota TVA in nomenclator</td>
              <td><code>Produsul ... nu are cota tva setata in cloud. Setati o cota din nomenclatorul de produse.</code></td>
              <td>Seteaza cota TVA a produsului in <a href="https://cloud.smartbill.ro/nomenclator/produse/">Nomenclatoare &gt; Produse</a>.</td>
            </tr>
            <tr>
              <td>Fara cota TVA implicita</td>
              <td><code>Cota default nu a fost gasita pe server!</code></td>
              <td>Marcheaza o cota TVA ca implicita in <a href="https://cloud.smartbill.ro/core/configurare/cote-tva/">Configurare > Cote TVA</a>.</td>
            </tr>
            <tr>
              <td>Cota discountului inexistenta</td>
              <td><code>Cota ... nu a fost gasita pe server!</code></td>
              <td>Foloseste o cota TVA predefinita in cont.</td>
            </tr>
            <tr>
              <td>Discount pe produse cu cote TVA diferite</td>
              <td><code>La aplicarea unui discount pentru produse cu cote tva diferite, trebuie sa specifici si cota tva a discountului.</code></td>
              <td>Specifica si cota TVA a discountului.</td>
            </tr>
            <tr>
              <td>Discount valoric fara valoare</td>
              <td><code>discountValue trebuie specificat pentru fiecare produs de tip discount</code></td>
              <td>Trimite `discountValue` pe linia de discount.</td>
            </tr>
            <tr>
              <td>Moneda produsului inexistenta</td>
              <td><code>Moneda nu a fost gasita pe server!</code></td>
              <td>Trimite o valoare acceptata de schema campului `products[].currency` sau omite campul.</td>
            </tr>
            <tr>
              <td>Moneda de referinta diferita</td>
              <td><code>Nu puteti emite documente in ... cu moneda de referinta a produselor in ... !</code></td>
              <td>Moneda documentului si cea de referinta trebuie sa coincida (cand nu e RON).</td>
            </tr>
            <tr>
              <td>Pret in alta moneda decat documentul</td>
              <td><code>Aveti produse care au pretul in alta moneda decat cea a facturii.</code></td>
              <td>Activeaza in cont lucrul cu pret de referinta in valuta.</td>
            </tr>
            <tr>
              <td>Peste 400 de linii pe document</td>
              <td><code>Numarul maxim acceptat de 400 intrari pe document a fost depasit.</code></td>
              <td>Maxim 400 de pozitii pe document.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Incasare</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Incasare fara tip (<code>payment.type</code> lipseste)</td>
              <td><code>type trebuie specificat pentru incasare</code></td>
              <td>Trimite tipul incasarii in `payment.type`.</td>
            </tr>
            <tr>
              <td>Incasare fara <code>isCash</code></td>
              <td><code>isCash trebuie specificat pentru incasare</code></td>
              <td>Trimite `payment.isCash` (`true`/`false`) cand adaugi o incasare.</td>
            </tr>
            <tr>
              <td>Incasare fara valoare (<code>payment.value</code> lipseste)</td>
              <td><code>value trebuie specificat pentru incasare</code></td>
              <td>Trimite valoarea incasarii in `payment.value`.</td>
            </tr>
            <tr>
              <td>Tip de incasare inexistent</td>
              <td><code>Tipul documentului nu a fost gasit pe server!</code></td>
              <td>Tipul de incasare trimis nu exista. Foloseste un tip valid (de exemplu `Chitanta`, `Ordin de plata`, `Card`).</td>
            </tr>
            <tr>
              <td>Serie de incasare inexistenta in cont</td>
              <td><code>Seria nu a fost gasita! Folositi o serie creata in contul de cloud.</code></td>
              <td>Seria incasarii trebuie definita in contul SmartBill Cloud.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Din proforma</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Proforma sursa inexistenta</td>
              <td><code>Factura proforma ... nu a fost gasita!</code></td>
              <td>Proforma pe baza careia vrei sa emiti factura nu a fost gasita. Verifica in SmartBill Cloud daca documentul mai exista si daca ai trimis corect seria si numarul proformei.</td>
            </tr>
            <tr>
              <td>Proforma sursa fara produse</td>
              <td><code>Proforma nu contine produse!</code></td>
              <td>Proforma pe baza careia emiti factura nu are produse adaugate. Verifica in SmartBill Cloud daca proforma respectiva are produse.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Stoc si gestiuni</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Gestiune lipsa pe produs (cu <code>useStock</code>)</td>
              <td><code>Gestiunea predatoare nu este setata pentru produsul Produs Test API Erori.</code></td>
              <td>Cand `useStock` este `true`, trimite o gestiune existenta in `products[].warehouseName`.</td>
            </tr>
            <tr>
              <td>Gestiune inexistenta in cont</td>
              <td><code>Gestiunea predatoare GESTIUNE_INEXISTENTA a produsului Produs Test API Erori nu a fost gasita.</code></td>
              <td>Verifica ca `warehouseName` este scrisa corect si ca gestiunea a fost creata in prealabil in contul Cloud.</td>
            </tr>
            <tr>
              <td>Gestiune invalida</td>
              <td><code>Gestiunea predatoare este invalida!</code></td>
              <td>Gestiunea trimisa nu este valida. Verifica `warehouseName` si gestiunile definite in contul Cloud.</td>
            </tr>
            <tr>
              <td>Modulul de stoc inactiv pe cont</td>
              <td><code>Modulul stoc nu este activ!</code></td>
              <td>Contul pe care emiti nu are activat modulul de gestiune. Contacteaza-ne la api@smartbill.ro.</td>
            </tr>
            <tr>
              <td>Produs fara stoc (nicio achizitie)</td>
              <td><code>Nu ai facut nicio achizitie pentru produsul ...</code></td>
              <td>Incarca intai stoc pentru produs sau emite documentul fara descarcare de gestiune. Verifica codul si numele produsului (case-sensitive).</td>
            </tr>
            <tr>
              <td>Stoc insuficient pe gestiune</td>
              <td><code>Cantitate stoc insuficienta ...</code></td>
              <td>Nu exista stoc suficient pe gestiunea aleasa. Schimba gestiunea sau emite cu `useStock` `false` si descarca stocul ulterior din contul Cloud.</td>
            </tr>
            <tr>
              <td>Cod produs care nu coincide cu cel din stoc</td>
              <td><code>Exista deja pe stoc un produs cu numele ... si codul ...</code></td>
              <td>Codul produsului trimis nu coincide exact cu cel din SmartBill. Codul este case-sensitive (de exemplu `25xl` vs `25XL`).</td>
            </tr>
            <tr>
              <td>Unitate de masura fara factor de conversie</td>
              <td><code>Unitatea de masura ... nu are factor de conversie setat.</code></td>
              <td>Unitatea de masura trebuie trecuta exact ca in contul Cloud pentru produs. Parametrul este case-sensitive.</td>
            </tr>
            <tr>
              <td>Data document anterioara importului de stoc initial</td>
              <td><code>Nu poti adauga documente cu tranzactii pe stoc la data anterioara datei importului de stoc initial ...</code></td>
              <td>Alege o `issueDate` ulterioara datei importului de stoc initial pentru gestiunea respectiva.</td>
            </tr>
          </tbody>
        </table>

        </details>

        - --

        ## Tipuri de emitere

        <details>
        <summary><strong>1. Emitere factura simpla</strong></summary>

        Campurile minime obligatorii pentru o factura valida. Punct de start recomandat pentru integrari noi sau cazuri simple.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "country": "Romania"
          },
          "products": [{
            "name": "Produs 1",
            "code": "PRD001",
            "quantity": 1,
            "measuringUnitName": "buc",
            "taxPercentage": 21,
            "price": 10
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>2. Emitere factura completa</strong></summary>

        Un payload complex care combina mai multe optiuni intr-un singur apel - util ca referinta cand integrezi scenarii care depasesc factura simpla.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "isDraft": false,
          "issueDate": "2026-06-15",
          "dueDate": "2026-07-15",
          "deliveryDate": "2026-06-20",
          "paymentDate": "2026-06-15",
          "language": "RO",
          "currency": "RON",
          "precision": 2,
          "useStock": false,
          "useIntraCif": false,
          "usePaymentTax": false,
          "useEstimateDetails": false,
          "delegateName": "Ion Popescu",
          "delegateIdentityCard": "AB 123456",
          "delegateAuto": "B-123-ABC",
          "issuerCnp": "1234567890123",
          "issuerName": "Maria Ionescu",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "code": "CLI001",
            "regCom": "J40/1234/2020",
            "isTaxPayer": true,
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania",
            "email": "client@example.com",
            "phone": "0722000000",
            "contact": "Andrei Popa",
            "iban": "RO49AAAA1B31007593840000",
            "bank": "BCR",
            "saveToDb": false
          },
          "products": [
            {
              "name": "Servicii consultanta",
              "code": "SRV001",
              "productDescription": "Servicii de consultanta IT",
              "translatedName": "Consulting services",
              "measuringUnitName": "ora",
              "translatedMeasuringUnit": "hour",
              "quantity": 1,
              "price": 100,
              "taxName": "Normala",
              "taxPercentage": 21,
              "isService": true,
              "saveToDb": false
            },
            {
              "name": "Discount valoric",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 1,
              "discountValue": -10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 2,
              "price": 200,
              "measuringUnitName": "buc",
              "taxName": "Normala",
              "taxPercentage": 21,
              "isService": false,
              "saveToDb": false
            },
            {
              "name": "Discount procentual 10%",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 2,
              "discountPercentage": 10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            }
          ],
          "payment": {
            "value": 450,
            "type": "Ordin plata",
            "isCash": false
          },
          "paymentUrl": "",
          "sendEmail": false,
          "email": {
            "to": "client@example.com",
            "cc": "",
            "bcc": ""
          },
          "observations": "Marfa se ridica de la sediu in termen de 5 zile lucratoare",
          "mentions": "Plata se face in contul IBAN specificat in contract"
        }
        ```

        </details>

        <details>
        <summary><strong>3. Emitere factura cu link de plata</strong></summary>

        Emite factura cu un link de plata asociat butonului 'Plateste cu cardul' de pe document. Necesita un cont Netopia, euPlatesc sau Stripe configurat in  <a href="https://cloud.smartbill.ro/core/integrari/">Configurare > Integrari</a>. Seteaza `paymentUrl: "Generate URL"` pentru a activa generarea link-ului.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }],
          "paymentUrl": "Generate URL"
        }
        ```

        </details>

        <details>
        <summary><strong>4. Emitere factura cu descarcare de gestiune</strong></summary>

        Emite factura si scade stocul produselor din gestiune. Gestiunea trebuie sa existe deja in SmartBill Cloud si sa aiba stoc disponibil pentru produsele facturate. Seteaza `useStock: true` si specifica `warehouseName` pe fiecare produs.

        > **Denumirea produsului la descarcarea de gestiune.** Produsul este identificat prin `code`. Daca valoarea din `name` difera de denumirea din nomenclator, aceasta suprascrie automat numele produsului in nomenclator, indiferent de valoarea `saveToDb`.
        >
        > *Exemplu:* produsul `Apa minerala` (cod `A1`) exista in nomenclator. La emiterea unei facturi cu descarcare de gestiune pe codul `A1`, transmitand `"name": "Apa minerala 1.5"`, denumirea produsului din nomenclator devine `Apa minerala 1.5`.
        >
        > Pentru a pastra denumirea din SmartBill, astfel incat numele transmis prin API sa fie folosit doar pe factura fara a modifica nomenclatorul, seteaza `useSBProductName: true` in parametrii produsului. Necesita setarea "Foloseste cod produs" activata pe firma.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "useStock": true,
          "products": [{
            "name": "Produs 1",
            "code": "PRD001",
            "quantity": 1,
            "price": 100,
            "measuringUnitName": "buc",
            "warehouseName": "NUME_GESTIUNE",
            "taxPercentage": 21
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>5. Emitere factura ciorna (draft)</strong></summary>

        Emite factura in stare de ciorna, fara numar atribuit. Documentul ramane ca ciorna pana la finalizare manuala din SmartBill Cloud. Seteaza `isDraft: true`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "isDraft": true,
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>6. Emitere factura cu discounturi</strong></summary>

        Discounturile se adauga ca linii separate cu `isDiscount: true`. `numberOfItems` stabileste pe cate produse imediat anterioare se aplica discountul. Pentru discount valoric, seteaza `discountType: 1` si foloseste `discountValue`. Pentru discount procentual, seteaza `discountType: 2` si foloseste `discountPercentage`; valoarea procentului trebuie sa fie mai mare decat 0.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 100,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Discount valoric",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 1,
              "discountValue": -10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Produs 2",
              "code": "PRD002",
              "quantity": 1,
              "price": 200,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Discount procentual 10%",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 2,
              "discountPercentage": 10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>7. Emitere factura cu servicii</strong></summary>

        Marcheaza produsele de tip serviciu cu `isService: true`. Serviciile sunt excluse automat din descarcarea de gestiune atunci cand `useStock: true` este setat la nivel de factura.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{
            "name": "Servicii consultanta",
            "code": "SRV001",
            "quantity": 1,
            "price": 100,
            "measuringUnitName": "ora",
            "taxPercentage": 21,
            "isService": true
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>8. Emitere factura cu data scadenta</strong></summary>

        Adauga `dueDate` pentru a specifica data scadentei facturii.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "dueDate": "2026-07-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>9. Emitere factura ca incasata</strong></summary>

        Emite factura si inregistreaza plata simultan, intr-un singur apel, prin obiectul `payment`. Util atunci cand clientul a platit comanda in magazinul tau online.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }],
          "payment": {
            "value": 100,
            "paymentSeries": "SERIA_CHITANTEI",
            "type": "Chitanta",
            "isCash": true
          }
        }
        ```

        </details>

        <details>
        <summary><strong>10. Emitere factura cu trimitere pe email</strong></summary>

        Emite factura si o trimite automat pe email clientului. Seteaza `sendEmail: true` si specifica adresa in `email.to`. Adresa de expeditor si template-ul se configureaza din [Configurare > Email](https://cloud.smartbill.ro/core/configurare_mailuri/).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "sendEmail": true,
          "email": {
            "to": "client@example.com",
            "cc": "",
            "bcc": ""
          },
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>11. Emitere factura in valuta</strong></summary>

        Emite factura in valuta. Seteaza `currency` si `exchangeRate` la nivel de factura, si `currency` pe fiecare produs cu aceeasi valuta - cursul apare pe factura alaturi de echivalentul in RON. `exchangeRate` este optional - daca nu e specificat, se foloseste cursul din [Preferinte personale](https://cloud.smartbill.ro/core/configurare/preferinte-personale/) (sectiunea "Curs valutar preluat de pe Internet": cursul de azi sau de ieri, cu adaos procentual optional).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "currency": "EUR",
          "exchangeRate": 4.97,
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 100,
              "measuringUnitName": "buc",
              "taxPercentage": 21,
              "currency": "EUR"
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>12. Emitere factura cu pret referinta in valuta</strong></summary>

        Util cand contractele sunt in valuta dar facturezi in RON - de exemplu, un abonament de mentenanta de 100 EUR facturat la cursul zilei. Necesita activarea optiunii "Am preturi cu moneda de referinta in valuta" din [Configurare > Generale](https://cloud.smartbill.ro/documente/preferinte-generale/) in SmartBill Cloud. Seteaza `currency` la nivel de produs cu valuta contractului si `currency` la nivel de factura cu moneda de emitere. `exchangeRate` pe produs este optional - daca nu e specificat, se foloseste cursul din [Preferinte personale](https://cloud.smartbill.ro/core/configurare/preferinte-personale/) (sectiunea "Curs valutar preluat de pe Internet": cursul de azi sau de ieri, cu adaos procentual optional).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "currency": "RON",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 497,
              "measuringUnitName": "buc",
              "taxPercentage": 21,
              "currency": "EUR",
              "exchangeRate": 4.97
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>13. Emitere factura cu CIF intracomunitar</strong></summary>

        Daca esti inregistrat in sistemul electronic One Stop Shop, intra in contul SmartBill la [Configurare > Date Firma](https://cloud.smartbill.ro/core/configurare/date-firma/) si completeaza campul `CIF intracomunitar`. Daca ai nevoie de CIF OSS, foloseste optiunea `Genereaza CIF OSS` afisata langa camp. Dupa configurare, seteaza `useIntraCif: true` pentru a emite factura cu acest CIF.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "useIntraCif": true,
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Company GmbH", "vatCode": "DE123456789", "address": "Musterstrasse 1", "city": "Berlin", "county": "Berlin", "country": "Germania" },
          "products": [{ "name": "Servicii consultanta", "code": "SRV001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 0, "taxName": "Taxare inversa", "isService": true }]
        }
        ```

        </details>

        <details>
        <summary><strong>14. Emitere factura - emitent neplatitor de TVA</strong></summary>

        Daca firma ta nu este platitoare de TVA, nu este necesar sa completezi campurile legate de TVA pe produse.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc" }]
        }
        ```

        </details>

        <details>
        <summary><strong>15. Emitere factura cu cote TVA diferite</strong></summary>

        Adauga produse cu cote TVA diferite ca linii separate cu `taxPercentage` corespunzator - SmartBill grupeaza automat pe cote in document. La cota 0%, specifica intotdeauna si un `taxName` existent in cont, de exemplu `Taxare inversa`, `TVA Inclus`, `SDD` sau `SFDD` - fara el, API-ul alege implicit `Taxare inversa`, indiferent de regimul fiscal corect.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            { "name": "Produs standard", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 },
            { "name": "Aliment", "code": "PRD002", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 11 },
            { "name": "Produs scutit", "code": "PRD003", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 0, "taxName": "SDD" }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>16. Emitere factura in limba straina</strong></summary>

        Factura se emite implicit in limba romana (`RO`). Pentru emiterea intr-o alta limba, seteaza parametrul `language` la nivelul facturii.

        Poti folosi o limba predefinita in SmartBill Cloud sau o limba definita de administrator in cont. Valoarea trimisa in `language` trebuie sa corespunda unei limbi disponibile in cont.

        `language` controleaza limba documentului, dar denumirea produselor si unitatile de masura trebuie traduse explicit pe fiecare produs, prin `translatedName` si `translatedMeasuringUnit`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "language": "EN",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{
            "name": "Produs 1",
            "translatedName": "Product 1",
            "code": "PRD001",
            "quantity": 1,
            "price": 100,
            "measuringUnitName": "buc",
            "translatedMeasuringUnit": "piece",
            "taxPercentage": 21
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>17. Emitere factura din proforma</strong></summary>

        Creeaza factura pe baza unei proforme existente. Nu e nevoie de client sau produse - se preiau din proforma.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "issueDate": "2026-06-15",
          "seriesName": "SERIA_FACTURII",
          "useEstimateDetails": true,
          "estimate": {
            "seriesName": "SERIA_PROFORMEI",
            "number": "0001"
          },
          "useStock": false
        }
        ```

        </details>

        <details>
        <summary><strong>18. Emitere factura cu observatii si mentiuni</strong></summary>

        Foloseste `observations` si `mentions` pentru textele afisate pe factura.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }],
          "observations": "Marfa se ridica de la sediu in termen de 5 zile lucratoare",
          "mentions": "Plata se face in contul IBAN specificat in contract"
        }
        ```

        </details>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceRequest'
            examples:
              factura_simpla:
                summary: "1. Emitere factura simpla"
                description: Campurile minime necesare pentru crearea unei facturi
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    country: Romania
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    measuringUnitName: buc
                    taxPercentage: 21
                    price: 10
              factura_completa:
                summary: "2. Emitere factura completa"
                description: Factura cu toate campurile disponibile - client complet cu adresa de livrare, delegat, emitent, produse cu discount, incasare si email
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  isDraft: false
                  issueDate: '2026-06-15'
                  dueDate: '2026-07-15'
                  deliveryDate: '2026-06-20'
                  paymentDate: '2026-06-15'
                  language: RO
                  currency: RON
                  precision: 2
                  useStock: false
                  useIntraCif: false
                  usePaymentTax: false
                  useEstimateDetails: false
                  delegateName: Ion Popescu
                  delegateIdentityCard: AB 123456
                  delegateAuto: B-123-ABC
                  issuerCnp: '1234567890123'
                  issuerName: Maria Ionescu
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    code: CLI001
                    regCom: J40/1234/2020
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                    phone: '0722000000'
                    contact: Andrei Popa
                    iban: RO49AAAA1B31007593840000
                    bank: BCR
                    saveToDb: false
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    productDescription: Servicii de consultanta IT
                    translatedName: Consulting services
                    measuringUnitName: ora
                    translatedMeasuringUnit: hour
                    quantity: 1
                    price: 100
                    taxName: Normala
                    taxPercentage: 21
                    isService: true
                    saveToDb: false
                  - name: Discount valoric
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 1
                    discountValue: -10
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Produs 1
                    code: PRD001
                    quantity: 2
                    price: 200
                    measuringUnitName: buc
                    taxName: Normala
                    taxPercentage: 21
                    isService: false
                    saveToDb: false
                  - name: Discount procentual 10%
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 2
                    discountPercentage: 10
                    measuringUnitName: buc
                    taxPercentage: 21
                  payment:
                    value: 450
                    type: Ordin plata
                    isCash: false
                  paymentUrl: ''
                  sendEmail: false
                  email:
                    to: client@example.com
                    cc: ''
                    bcc: ''
                  observations: Marfa se ridica de la sediu in termen de 5 zile lucratoare
                  mentions: Plata se face in contul IBAN specificat in contract
              cu_link_plata:
                summary: "3. Emitere factura cu link de plata"
                description: Genereaza factura cu link de plata online pentru client
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: &client_exemplu
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  paymentUrl: Generate URL
              cu_descarcare_gestiune:
                summary: "4. Emitere factura cu descarcare de gestiune"
                description: Descarca inventarul din gestiune cand se creeaza factura
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  useStock: true
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    warehouseName: NUME_GESTIUNE
                    taxPercentage: 21
              ca_ciorna:
                summary: "5. Emitere factura ciorna (draft)"
                description: Creeaza factura ca ciorna - fara numar atribuit pana la finalizare
                value:
                  companyVatCode: CIF_FIRMA
                  isDraft: true
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              cu_discounturi:
                summary: "6. Emitere factura cu discounturi"
                description: Include discount valoric si discount procentual in acelasi payload
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Discount valoric
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 1
                    discountValue: -10
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Produs 2
                    code: PRD002
                    quantity: 1
                    price: 200
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Discount procentual 10%
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 2
                    discountPercentage: 10
                    measuringUnitName: buc
                    taxPercentage: 21
              cu_servicii:
                summary: "7. Emitere factura cu servicii"
                description: Foloseste isService pentru linii de serviciu
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    quantity: 1
                    price: 100
                    measuringUnitName: ora
                    taxPercentage: 21
                    isService: true
              cu_data_scadenta:
                summary: "8. Emitere factura cu data scadenta"
                description: Seteaza dueDate pentru data scadenta
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  dueDate: '2026-07-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              ca_incasata:
                summary: "9. Emitere factura ca incasata"
                description: Creeaza factura si inregistreaza plata simultan
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  payment:
                    value: 100
                    paymentSeries: SERIA_CHITANTEI
                    type: Chitanta
                    isCash: true
              cu_email:
                summary: "10. Emitere factura cu trimitere pe email"
                description: Creeaza factura si o trimite clientului prin email
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  sendEmail: true
                  email:
                    to: client@example.com
                    cc: ''
                    bcc: ''
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              in_valuta:
                summary: "11. Emitere factura in valuta"
                description: Creeaza factura in EUR cu curs de schimb
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  currency: EUR
                  exchangeRate: 4.97
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                    currency: EUR
              pret_referinta_valuta:
                summary: "12. Emitere factura cu pret referinta in valuta"
                description: Factura in RON cu produse al caror pret de referinta este in valuta straina
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  currency: RON
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 497
                    measuringUnitName: buc
                    taxPercentage: 21
                    currency: EUR
                    exchangeRate: 4.97
              cif_intracomunitar:
                summary: "13. Emitere factura cu CIF intracomunitar"
                description: Emitere pentru client din UE cu cod TVA intracomunitar
                value:
                  companyVatCode: CIF_FIRMA
                  useIntraCif: true
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client:
                    name: Company GmbH
                    vatCode: DE123456789
                    address: "Musterstrasse 1"
                    city: Berlin
                    county: Berlin
                    country: Germania
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 0
                    taxName: Taxare inversa
                    isService: true
              emitent_neplatitor_tva:
                summary: "14. Emitere factura - emitent neplatitor de TVA"
                description: Emitere factura fara TVA pe produse
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 0
                    taxName: Taxare inversa
              cote_tva_diferite:
                summary: "15. Emitere factura cu cote TVA diferite"
                description: Factura cu produse la cote TVA diferite
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs standard
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Aliment
                    code: PRD002
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 11
                  - name: Produs scutit
                    code: PRD003
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 0
                    taxName: SDD
              factura_limba_straina:
                summary: "16. Emitere factura in limba straina"
                description: Factura emisa intr-o alta limba
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  language: EN
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    translatedName: Product 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    translatedMeasuringUnit: piece
                    taxPercentage: 21
              din_proforma:
                summary: "17. Emitere factura din proforma"
                description: Creeaza factura pe baza unei proforme existente
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  useEstimateDetails: true
                  estimate:
                    seriesName: SERIA_PROFORMEI
                    number: '0001'
                  useStock: false
              cu_observatii_mentiuni:
                summary: "18. Emitere factura cu observatii si mentiuni"
                description: Adauga observatii si mentiuni pe factura
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  observations: Marfa se ridica de la sediu in termen de 5 zile lucratoare
                  mentions: Plata se face in contul IBAN specificat in contract
      responses:
        '200':
          description: Raspuns V1. `errorText` gol inseamna succes; `errorText` completat inseamna eroare functionala.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceResponseV2'
              examples:
                success:
                  summary: Factura creata cu succes
                  value:
                    errorText: ''
                    message: ''
                    number: '0007'
                    series: ff
                    url: ''
                    documentUrl: https://cloud.smartbill.ro/documente/editare/factura/20363/
                    documentId: 20363
                    documentViewUrl: https://cloud.smartbill.ro/documente/extern/pf/factura/f6a9a7d3...?srvid=2
        '400':
          description: |
            Eroare functionala V1. Toate erorile 400 au aceeasi forma (`errorText` + envelope-ul standard). Exemplele de mai jos arata doar forma raspunsului; lista completa de mesaje si cum le rezolvi e in tabelele din descrierea endpoint-ului (sectiunea "Ai primit o eroare...").
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_series:
                  summary: Seria nu exista in cont
                  value:
                    errorText: "Seria nu a fost gasita! Folositi o serie creata in contul de cloud."
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
                client_name_empty:
                  summary: Nume client invalid sau lipsa
                  value:
                    errorText: "Client invalid!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
                products_empty:
                  summary: Lista produse goala
                  value:
                    errorText: "invoiceProducts trebuie specificat si trebuie sa contina cel putin un element"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
        '410':
          description: Limita document depasita
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                too_many_lines:
                  summary: Depasit limita de 400 pozitii pe document
                  value:
                    errorText: "Numarul maxim acceptat de 400 intrari pe document a fost depasit."
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
        '500':
          description: Eroare interna V1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                company_vat_code_null:
                  summary: companyVatCode trimis ca null
                  value:
                    errorText: "Internal Server Error!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: null
                    documentViewUrl: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /invoice/reverse:
    post:
      tags:
      - Facturi
      summary: Emitere factura storno
      operationId: createStornoInvoice
      security:
      - basicAuth: []
      description: |
        Storneaza o factura existenta. Trimite seria si numarul facturii originale; `issueDate` este optional.

        **Ai primit o eroare la emiterea facturii storno?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `companyVatCode`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice stornarii.

        <details>
        <summary><strong>Erori la emiterea facturii storno</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste</td>
              <td><code>Numarul facturii trebuie specificat in parametrul 'number'!</code></td>
              <td>Trimite `number` cu numarul facturii de stornat, exact ca in cont, de exemplu `3738`.</td>
            </tr>
            <tr>
              <td><code>seriesName</code> lipseste</td>
              <td><code>Seria facturii trebuie specificata in parametrul 'seriesname'!</code></td>
              <td>Trimite `seriesName` cu seria facturii de stornat, de exemplu `fac`.</td>
            </tr>
            <tr>
              <td>Factura de stornat nu exista</td>
              <td><code>Factura cu seria si numarul fac99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesName` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
            <tr>
              <td>Factura a fost deja stornata</td>
              <td><code>Factura este deja stornata.</code></td>
              <td>O factura poate fi stornata o singura data. Verifica daca exista deja o factura storno pentru acest document.</td>
            </tr>
            <tr>
              <td>Factura de stornat este anulata</td>
              <td><code>Factura fac3830 este anulata.</code></td>
              <td>Nu poti storna o factura anulata. Restaureaz-o intai (daca chiar vrei sa o stornezi) sau storneaza o factura activa.</td>
            </tr>
            <tr>
              <td>Incerci sa stornezi o factura care e ea insasi storno</td>
              <td><code>Factura fac3739 este de tip storno. Nu se poate storna.</code></td>
              <td>Nu se poate storna un document de tip storno. Trimite in `number` factura originala, nu factura storno.</td>
            </tr>
            <tr>
              <td><code>issueDate</code> anterioara datei facturii originale</td>
              <td><code>Data emiterii facturii storno nu poate fi anterioara datei emiterii facturii stornate.</code></td>
              <td>Trimite `issueDate` egala sau ulterioara datei facturii stornate.</td>
            </tr>
            <tr>
              <td><code>issueDate</code> in format gresit</td>
              <td><code>Could not map property: issueDate.</code></td>
              <td>Trimite `issueDate` in format `yyyy-MM-dd`, de exemplu `2026-07-15`.</td>
            </tr>
          </tbody>
        </table>

        </details>

        - --

        ## Tipuri de stornare

        <details>
        <summary><strong>1. Storno simplu</strong></summary>

        Stornarea unei facturi existente. Storno-ul preia automat seria facturii originale si primeste data curenta.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "number": "3738"
        }
        ```

        </details>

        <details>
        <summary><strong>2. Storno cu data specifica</strong></summary>

        Seteaza `issueDate` cand vrei ca factura storno sa aiba o data diferita de cea curenta. Data nu poate fi anterioara datei facturii originale.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_FACTURII",
          "number": "3738",
          "issueDate": "2026-07-15"
        }
        ```

        </details>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - companyVatCode
              - seriesName
              - number
              properties:
                companyVatCode:
                  type: string
                  description: CIF-ul firmei tale.
                seriesName:
                  type: string
                  description: Seria facturii originale.
                number:
                  type: string
                  description: Numarul facturii originale.
                issueDate:
                  type: string
                  format: date
                  description: Data facturii storno. Daca lipseste, se foloseste data curenta.
            examples:
              storno_simplu:
                summary: "1. Storno simplu"
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  number: '3738'
              storno_cu_data:
                summary: "2. Storno cu data specifica"
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  number: '3738'
                  issueDate: '2026-07-15'
      responses:
        '200':
          description: Factura storno creata cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceResponse'
              example:
                errorText: ''
                message: ''
                number: '3739'
                series: SERIA_FACTURII
                url: ''
                documentId: 302368801
                documentUrl: https://cloud.smartbill.ro/documente/editare/factura/302368801/
                documentViewUrl: https://cloud.smartbill.ro/documente/extern/pf/factura/...
        '400':
          description: Operatiune invalida - factura negasita sau storno imposibil
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul facturii trebuie specificat in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesName lipsa
                  value:
                    errorText: "Seria facturii trebuie specificata in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                factura_negasita:
                  summary: Factura de stornat nu exista
                  value:
                    errorText: Factura cu seria si numarul fac99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                data_anterioara:
                  summary: Data storno anterioara facturii originale
                  value:
                    errorText: Data emiterii facturii storno nu poate fi anterioara datei emiterii facturii stornate.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                deja_stornata:
                  summary: Factura a fost deja stornata
                  value:
                    errorText: Factura este deja stornata.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                factura_de_tip_storno:
                  summary: Nu se poate storna o factura storno
                  value:
                    errorText: Factura fac3739 este de tip storno. Nu se poate storna.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                format_data_invalid:
                  summary: issueDate in format gresit (eroare de mapare JSON)
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/invoice/reverse
                    errors:
                    - code: json_mapping_error
                      message: 'Could not map property: issueDate.'
                      docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
                      param: issueDate
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/ServerError'
  /invoice/pdf:
    get:
      tags:
      - Facturi
      summary: Descarcare factura PDF
      operationId: getInvoicePdf
      security:
      - basicAuth: []
      description: |
        Descarca factura in format PDF. Parametrii se trimit in URL (query string).

        Factura poate fi preluata prin API doar ca fisier PDF. Nu exista endpoint pentru factura in format JSON sau XML.

        Raspunsul de succes este un fisier binar (`application/octet-stream`), trimis cu `Content-Disposition: attachment` si cu numele fisierului format din `factura` + serie + numar - de exemplu `facturafac3880.pdf`.

        `Content-Type` din raspuns oglindeste header-ul `Accept` trimis in cerere: daca ceri `Accept: application/json`, raspunsul e etichetat `application/json`, desi corpul ramane acelasi PDF. Nu te baza pe `Content-Type` ca sa decizi cum tratezi raspunsul.

        **Nu trimite `Accept: application/pdf`.** Valoarea cea mai naturala e singura care nu merge: raspunsul e `406` cu `{"code": "invalid_accept_header"}`, nu PDF-ul. Merg `application/octet-stream`, `*/*`, `application/json` sau lipsa completa a header-ului `Accept`.

        Atentie la erori: acest endpoint **nu** intoarce o eroare de API. Orice parametru lipsa sau document inexistent duce la `502 Bad Gateway`, cu corp HTML, care nu se poate interpreta programatic. Spre deosebire de el, [proforma in PDF](#tag/proforme/GET/estimate/pdf) intoarce `400` cu `errorText` in JSON.
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Seria facturii
        schema:
          type: string
        example: SERIA_FACTURII
      - name: number
        in: query
        required: true
        description: Numarul facturii
        schema:
          type: string
        example: '3769'
      responses:
        '200':
          description: |
            Fisierul PDF al facturii, ca flux binar (`application/octet-stream`). Salveaza-l intr-un fisier `.pdf`.
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '502':
          description: |
            Parametri lipsa sau factura inexistenta. Verifica `seriesname`, `number` si existenta facturii.
          content:
            text/html:
              schema:
                type: string
              example: |
                <html>
                <head><title>502 Bad Gateway</title></head>
                <body>
                <center><h1>502 Bad Gateway</h1></center>
                <hr><center>nginx</center>
                </body>
                </html>
        '401':
          $ref: '#/components/responses/Unauthorized'
  /invoice/paymentstatus:
    get:
      tags:
      - Facturi
      summary: Verificare incasare factura
      operationId: getInvoicePaymentStatus
      security:
      - basicAuth: []
      description: |
        Verifica daca o factura este incasata si ce suma mai ramane de incasat. Parametrii se trimit in URL (query string).

        **Ce intorc campurile:**

        - `invoiceTotalAmount` - valoarea totala a facturii (cu TVA).
        - `paidAmount` - suma incasata pana acum.
        - `unpaidAmount` - suma ramasa de incasat (`invoiceTotalAmount - paidAmount`).
        - `paid` - `true` daca factura e incasata integral, altfel `false`.

        **Ai primit o eroare la verificarea incasarii?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice acestui endpoint.

        <details>
        <summary><strong>Erori la verificarea incasarii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul facturii trebuie specificat</code></td>
              <td>Adauga `number` in query string cu numarul facturii, de exemplu `number=3762`.</td>
            </tr>
            <tr>
              <td>Serie lipsa, serie gresita sau factura inexistenta</td>
              <td><code>Factura nu a fost gasita</code></td>
              <td>Verifica `seriesname` si `number`. Daca lipseste seria sau combinatia serie plus numar nu exista, API-ul raspunde cu acelasi mesaj.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Seria facturii
        schema:
          type: string
        example: SERIA_FACTURII
      - name: number
        in: query
        required: true
        description: Numarul facturii
        schema:
          type: string
        example: '3762'
      responses:
        '200':
          description: Statusul platii facturii
          content:
            application/json:
              schema:
                type: object
                properties:
                  errorText:
                    type: string
                  invoiceTotalAmount:
                    type: number
                    description: Valoarea totala a facturii (cu TVA)
                  paidAmount:
                    type: number
                    description: Suma incasata pana acum
                  unpaidAmount:
                    type: number
                    description: Suma ramasa de incasat
                  paid:
                    type: boolean
                    description: true daca factura e incasata integral
              example:
                errorText: ''
                message: ''
                number: ''
                series: ''
                url: ''
                invoiceTotalAmount: 121.0
                paidAmount: 0
                unpaidAmount: 121.0
                paid: false
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: Numarul facturii trebuie specificat
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    paid: false
                factura_negasita:
                  summary: Serie lipsa sau factura inexistenta
                  value:
                    errorText: Factura nu a fost gasita
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    paid: false
        '401':
          $ref: '#/components/responses/Unauthorized'
  /invoice/cancel:
    put:
      tags:
      - Facturi
      summary: Anulare factura
      operationId: cancelInvoice
      security:
      - basicAuth: []
      description: |
        Anuleaza o factura existenta. Factura anulata poate fi restaurata ulterior. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la anulare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice anularii.

        <details>
        <summary><strong>Erori la anulare</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul facturii trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul facturii de anulat, de exemplu `number=3744`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria facturii trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria facturii de anulat, de exemplu `seriesname=fac`.</td>
            </tr>
            <tr>
              <td>Factura de anulat nu exista</td>
              <td><code>Factura cu seria si numarul fac99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        schema:
          type: string
        example: SERIA_FACTURII
      - name: number
        in: query
        required: true
        schema:
          type: string
        example: '0025'
      responses:
        '200':
          description: |
            Factura anulata cu succes. Daca factura era deja anulata, raspunsul e tot `200` cu un mesaj informativ (anularea e idempotenta).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              examples:
                anulata:
                  summary: Factura anulata cu succes
                  value:
                    errorText: ''
                    message: Factura cu seria si numarul fac3744 a fost anulata cu succes.
                    number: ''
                    series: ''
                    url: ''
                deja_anulata:
                  summary: Factura era deja anulata (idempotent)
                  value:
                    errorText: ''
                    message: Factura fac3744 este deja anulata.
                    number: ''
                    series: ''
                    url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul facturii trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria facturii trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                factura_negasita:
                  summary: Factura nu exista
                  value:
                    errorText: Factura cu seria si numarul fac99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /invoice/restore:
    put:
      tags:
      - Facturi
      summary: Restaurare factura anulata
      operationId: restoreInvoice
      security:
      - basicAuth: []
      description: |
        Restaureaza o factura anulata anterior. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la restaurare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice restaurarii.

        <details>
        <summary><strong>Erori la restaurare</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul facturii trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul facturii de restaurat, de exemplu `number=3744`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria facturii trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria facturii de restaurat, de exemplu `seriesname=fac`.</td>
            </tr>
            <tr>
              <td>Factura de restaurat nu exista</td>
              <td><code>Factura cu seria si numarul fac99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
            <tr>
              <td>Factura nu este anulata</td>
              <td><code>Factura fac3859 nu necesita restaurare.</code></td>
              <td>Nu este o eroare: raspunsul are `errorText` gol si factura ramane neschimbata.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        schema:
          type: string
        example: SERIA_FACTURII
      - name: number
        in: query
        required: true
        schema:
          type: string
        example: '0025'
      responses:
        '200':
          description: |
            Factura restaurata cu succes. Daca factura nu era anulata, raspunsul e tot `200` cu un mesaj informativ (restaurarea e idempotenta).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              examples:
                restaurata:
                  summary: Factura restaurata cu succes
                  value:
                    errorText: ''
                    message: Factura cu seria si numarul fac3744 a fost restaurata cu succes.
                    number: ''
                    series: ''
                    url: ''
                nu_necesita:
                  summary: Factura nu era anulata (idempotent)
                  value:
                    errorText: ''
                    message: Factura fac3748 nu necesita restaurare.
                    number: ''
                    series: ''
                    url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul facturii trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria facturii trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                factura_negasita:
                  summary: Factura nu exista
                  value:
                    errorText: Factura cu seria si numarul fac99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /invoice:
    delete:
      tags:
      - Facturi
      summary: Stergere factura
      operationId: deleteInvoice
      security:
      - basicAuth: []
      description: |
        Sterge definitiv o factura. Poate fi stearsa doar ultima factura din serie. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la stergere?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice stergerii.

        <details>
        <summary><strong>Erori la stergere</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Factura nu e ultima din serie</td>
              <td><code>Nu poti sterge documentul cu seria si numarul fac 3749, deoarece nu este ultimul din serie!</code></td>
              <td>Doar ultima factura din serie poate fi stearsa. Pentru o factura din mijlocul seriei foloseste anularea in loc de stergere.</td>
            </tr>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul facturii trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul facturii de sters, de exemplu `number=3749`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria facturii trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria facturii de sters, de exemplu `seriesname=fac`.</td>
            </tr>
            <tr>
              <td>Factura de sters nu exista</td>
              <td><code>Factura cu seria si numarul fac99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: Your company's VAT code (CIF)
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Invoice series name
        schema:
          type: string
        example: SERIA_FACTURII
      - name: number
        in: query
        required: true
        description: Invoice number
        schema:
          type: string
        example: '0025'
      responses:
        '200':
          description: Factura stearsa cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                errorText: ''
                message: Factura cu seria si numarul fac3749 a fost stearsa cu succes.
                number: ''
                series: ''
                url: ''
        '400':
          description: Date invalide sau campuri lipsa
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul facturii trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria facturii trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                factura_negasita:
                  summary: Factura nu exista
                  value:
                    errorText: Factura cu seria si numarul fac99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '403':
          description: Factura nu e ultima din serie si nu poate fi stearsa
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errorText: Nu poti sterge documentul cu seria si numarul fac 3749, deoarece nu este ultimul din serie!
                message: ''
                number: ''
                series: ''
                url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate/v2:
    post:
      tags:
      - Proforme
      summary: Emitere proforma
      operationId: createEstimateV2
      security:
      - basicAuth: []
      description: |
        Emite o proforma noua. Poti emite proforma ca ciorna (draft), pe care o finalizezi ulterior din interfata SmartBill.

        **Ai primit o eroare la emiterea proformei?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `companyVatCode`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice emiterii de proforma.

        <strong>Erori la emiterea proformei</strong>

        <details>
        <summary><strong>Date document si serii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Serie inexistenta in cont</td>
              <td><code>Seria nu a fost gasita! Folositi o serie creata in contul de cloud.</code></td>
              <td>Seria trebuie definita in SmartBill Cloud. Trimite in `seriesName` seria proformei, exact cum e configurata in cont.</td>
            </tr>
            <tr>
              <td>Contul a atins numarul maxim de documente permis de pachetul de abonament</td>
              <td><code>Pentru acest pachet s-a emis numarul maxim de documente permis</code></td>
              <td>Limita vine din abonamentul contului SmartBill Cloud, nu din API, deci nu se ridica din integrare. Verifica pachetul in cont.</td>
            </tr>
            <tr>
              <td>Moneda inexistenta sau scrisa gresit</td>
              <td><code>Moneda nu a fost gasita pe server!</code></td>
              <td>Verifica moneda trimisa in `currency`. Valorile acceptate sunt listate in schema campului.</td>
            </tr>
            <tr>
              <td>Data documentului in format gresit</td>
              <td><code>Data documentului trebuie sa fie de forma yyyy-MM-dd.</code></td>
              <td>Trimite `issueDate` in format `yyyy-MM-dd`, de exemplu `2026-06-15`.</td>
            </tr>
            <tr>
              <td><code>sendEmail</code> fara adresa destinatar</td>
              <td><code>Trebuie specificata adresa de email a clientului.</code></td>
              <td>Cand `sendEmail` e `true`, completeaza adresa destinatarului in `email.to` sau in `client.email`.</td>
            </tr>
            <tr>
              <td><code>sendEmail</code> fara server de email</td>
              <td><code>Server-ul de email nu a fost configurat.</code></td>
              <td>Contul nu are un server de email configurat. Intra in SmartBill Cloud si configureaza-ti propriul server de email din <a href="https://cloud.smartbill.ro/core/configurare_mailuri/">Configurare > Email</a>.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Client</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Obiectul <code>client</code> lipseste</td>
              <td><code>tara trebuie specificata</code></td>
              <td>Trimite `client` cu cel putin `name` si `country`.</td>
            </tr>
            <tr>
              <td><code>client.name</code> gol sau <code>null</code></td>
              <td><code>Client invalid!</code></td>
              <td>Trimite un `client.name` valid (nu gol, nu `null`).</td>
            </tr>
            <tr>
              <td><code>client.country</code> lipseste</td>
              <td><code>tara trebuie specificata</code></td>
              <td>Completeaza `client.country`, ex. `Romania`.</td>
            </tr>
            <tr>
              <td>Client duplicat in nomenclator</td>
              <td><code>Clientul exista deja pe server</code></td>
              <td>Exista deja un client cu acelasi nume dar alt CIF. Sterge duplicatul din nomenclator.</td>
            </tr>
          </tbody>
        </table>

        </details>

        <details>
        <summary><strong>Produse, TVA si discounturi</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Lista `products` goala</td>
              <td><code>estimateProducts trebuie specificat si trebuie sa contina cel putin un element</code></td>
              <td>Trimite cel putin un produs in `products`.</td>
            </tr>
            <tr>
              <td><code>products[].name</code> lipsa</td>
              <td><code>name trebuie specificat pentru fiecare produs</code></td>
              <td>Trimite `name` la fiecare produs.</td>
            </tr>
            <tr>
              <td><code>products[].measuringUnitName</code> lipsa</td>
              <td><code>measuringUnitName trebuie specificat pentru fiecare produs</code></td>
              <td>Trimite `measuringUnitName` (case-sensitive, sa existe in cont).</td>
            </tr>
            <tr>
              <td>Cota TVA a produsului inexistenta</td>
              <td><code>Cota tva a produsului ... nu a fost gasita pe server!</code></td>
              <td>Foloseste o cota TVA existenta in cont.</td>
            </tr>
            <tr>
              <td>Produs fara cota TVA setata</td>
              <td><code>Trebuie sa setezi o cota tva pentru produsul ...</code></td>
              <td>Seteaza `taxPercentage` la fiecare produs.</td>
            </tr>
            <tr>
              <td>Document doar cu discount</td>
              <td><code>Nu poti sa emiti un document care contine doar un discount. Trebuie sa ai si produse / servicii adaugate.</code></td>
              <td>Adauga si produse, nu doar linie de discount.</td>
            </tr>
            <tr>
              <td>Discount procentual fara procent</td>
              <td><code>Trebuie sa introduceti valoarea procentului!</code></td>
              <td>Trimite `discountPercentage` pe linia de discount.</td>
            </tr>
            <tr>
              <td>Produs fara cod</td>
              <td><code>Produsul ... nu are codul specificat.</code></td>
              <td>Daca firma foloseste cod produs, trimite `code` la fiecare produs.</td>
            </tr>
            <tr>
              <td>Produs fara cota TVA in nomenclator</td>
              <td><code>Produsul ... nu are cota tva setata in cloud. Setati o cota din nomenclatorul de produse.</code></td>
              <td>Seteaza cota TVA a produsului in <a href="https://cloud.smartbill.ro/nomenclator/produse/">Nomenclatoare &gt; Produse</a>.</td>
            </tr>
            <tr>
              <td>Fara cota TVA implicita</td>
              <td><code>Cota default nu a fost gasita pe server!</code></td>
              <td>Marcheaza o cota TVA ca implicita in <a href="https://cloud.smartbill.ro/core/configurare/cote-tva/">Configurare > Cote TVA</a>.</td>
            </tr>
            <tr>
              <td>Cota discountului inexistenta</td>
              <td><code>Cota ... nu a fost gasita pe server!</code></td>
              <td>Foloseste o cota TVA predefinita in cont.</td>
            </tr>
            <tr>
              <td>Discount pe produse cu cote TVA diferite</td>
              <td><code>La aplicarea unui discount pentru produse cu cote tva diferite, trebuie sa specifici si cota tva a discountului.</code></td>
              <td>Specifica si cota TVA a discountului.</td>
            </tr>
            <tr>
              <td>Discount valoric fara valoare</td>
              <td><code>discountValue trebuie specificat pentru fiecare produs de tip discount</code></td>
              <td>Trimite `discountValue` pe linia de discount.</td>
            </tr>
            <tr>
              <td>Moneda produsului inexistenta</td>
              <td><code>Moneda nu a fost gasita pe server!</code></td>
              <td>Trimite o valoare acceptata de schema campului `products[].currency` sau omite campul.</td>
            </tr>
            <tr>
              <td>Moneda de referinta diferita</td>
              <td><code>Nu puteti emite documente in ... cu moneda de referinta a produselor in ... !</code></td>
              <td>Moneda documentului si cea de referinta trebuie sa coincida (cand nu e RON).</td>
            </tr>
            <tr>
              <td>Pret in alta moneda decat documentul</td>
              <td><code>Aveti produse care au pretul in alta moneda decat cea a proformei.</code></td>
              <td>Activeaza in cont lucrul cu pret de referinta in valuta.</td>
            </tr>
            <tr>
              <td>Peste 400 de linii pe document</td>
              <td><code>Numarul maxim acceptat de 400 intrari pe document a fost depasit.</code></td>
              <td>Maxim 400 de pozitii pe document.</td>
            </tr>
          </tbody>
        </table>

        </details>

        ## Tipuri de emitere

        <details>
        <summary><strong>1. Emitere proforma simpla</strong></summary>

        Campurile minime obligatorii pentru o proforma valida. Punct de start recomandat pentru integrari noi sau cazuri simple.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "country": "Romania"
          },
          "products": [{
            "name": "Produs 1",
            "code": "PRD001",
            "quantity": 1,
            "measuringUnitName": "buc",
            "taxPercentage": 21,
            "price": 10
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>2. Emitere proforma completa</strong></summary>

        Un payload complex care combina mai multe optiuni intr-un singur apel - util ca referinta cand integrezi scenarii care depasesc proforma simpla.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "isDraft": false,
          "issueDate": "2026-06-15",
          "dueDate": "2026-07-15",
          "deliveryDate": "2026-06-20",
          "language": "RO",
          "currency": "RON",
          "precision": 2,
          "useIntraCif": false,
          "delegateName": "Ion Popescu",
          "delegateIdentityCard": "AB 123456",
          "delegateAuto": "B-123-ABC",
          "issuerCnp": "1234567890123",
          "issuerName": "Maria Ionescu",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "code": "CLI001",
            "regCom": "J40/1234/2020",
            "isTaxPayer": true,
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania",
            "email": "client@example.com",
            "phone": "0722000000",
            "contact": "Andrei Popa",
            "iban": "RO49AAAA1B31007593840000",
            "bank": "BCR",
            "saveToDb": false
          },
          "products": [
            {
              "name": "Servicii consultanta",
              "code": "SRV001",
              "productDescription": "Servicii de consultanta IT",
              "translatedName": "Consulting services",
              "measuringUnitName": "ora",
              "translatedMeasuringUnit": "hour",
              "quantity": 1,
              "price": 100,
              "taxName": "Normala",
              "taxPercentage": 21,
              "isService": true,
              "saveToDb": false
            },
            {
              "name": "Discount valoric",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 1,
              "discountValue": -10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 2,
              "price": 200,
              "measuringUnitName": "buc",
              "taxName": "Normala",
              "taxPercentage": 21,
              "isService": false,
              "saveToDb": false
            },
            {
              "name": "Discount procentual 10%",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 2,
              "discountPercentage": 10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            }
          ],
          "paymentUrl": "",
          "sendEmail": false,
          "email": {
            "to": "client@example.com",
            "cc": "",
            "bcc": ""
          },
          "observations": "Marfa se ridica de la sediu in termen de 5 zile lucratoare",
          "mentions": "Plata se face in contul IBAN specificat in contract"
        }
        ```

        </details>

        <details>
        <summary><strong>3. Emitere proforma cu link de plata</strong></summary>

        Emite proforma cu un link de plata asociat butonului 'Plateste cu cardul' de pe document. Necesita un cont Netopia, euPlatesc sau Stripe configurat in <a href="https://cloud.smartbill.ro/core/integrari/">Contul Meu > Integrari</a>. Seteaza `paymentUrl: "Generate URL"` pentru a activa generarea link-ului.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }],
          "paymentUrl": "Generate URL"
        }
        ```

        </details>

        <details>
        <summary><strong>4. Emitere proforma ciorna (draft)</strong></summary>

        Emite proforma in stare de ciorna, fara numar atribuit. Documentul ramane ca ciorna pana la finalizare manuala din SmartBill Cloud. Seteaza `isDraft: true`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "isDraft": true,
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>5. Emitere proforma cu discounturi</strong></summary>

        Discounturile se adauga ca linii separate cu `isDiscount: true`. `numberOfItems` stabileste pe cate produse imediat anterioare se aplica discountul. Pentru discount valoric, seteaza `discountType: 1` si foloseste `discountValue`. Pentru discount procentual, seteaza `discountType: 2` si foloseste `discountPercentage`; valoarea procentului trebuie sa fie mai mare decat 0.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 100,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Discount valoric",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 1,
              "discountValue": -10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Produs 2",
              "code": "PRD002",
              "quantity": 1,
              "price": 200,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            },
            {
              "name": "Discount procentual 10%",
              "isDiscount": true,
              "numberOfItems": 1,
              "discountType": 2,
              "discountPercentage": 10,
              "measuringUnitName": "buc",
              "taxPercentage": 21
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>6. Emitere proforma cu servicii</strong></summary>

        Marcheaza produsele de tip serviciu cu `isService: true`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{
            "name": "Servicii consultanta",
            "code": "SRV001",
            "quantity": 1,
            "price": 100,
            "measuringUnitName": "ora",
            "taxPercentage": 21,
            "isService": true
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>7. Emitere proforma cu data scadenta</strong></summary>

        Adauga `dueDate` pentru a specifica data scadentei proformei.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "dueDate": "2026-07-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>8. Emitere proforma cu trimitere pe email</strong></summary>

        Emite proforma si o trimite automat pe email clientului. Seteaza `sendEmail: true` si specifica adresa in `email.to`. Adresa de expeditor si template-ul se configureaza din [Configurare > Email](https://cloud.smartbill.ro/core/configurare_mailuri/).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "sendEmail": true,
          "email": {
            "to": "client@example.com",
            "cc": "",
            "bcc": ""
          },
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }]
        }
        ```

        </details>

        <details>
        <summary><strong>9. Emitere proforma in valuta</strong></summary>

        Emite proforma in valuta. Seteaza `currency` si `exchangeRate` la nivel de proforma, si `currency` pe fiecare produs cu aceeasi valuta - cursul apare pe proforma alaturi de echivalentul in RON. `exchangeRate` este optional - daca nu e specificat, se foloseste cursul din [Preferinte personale](https://cloud.smartbill.ro/core/configurare/preferinte-personale/) (sectiunea "Curs valutar preluat de pe Internet": cursul de azi sau de ieri, cu adaos procentual optional).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "currency": "EUR",
          "exchangeRate": 4.97,
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 100,
              "measuringUnitName": "buc",
              "taxPercentage": 21,
              "currency": "EUR"
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>10. Emitere proforma cu pret referinta in valuta</strong></summary>

        Util cand contractele sunt in valuta dar emiti proforma in RON - de exemplu, un abonament de mentenanta de 100 EUR emis la cursul zilei. Necesita activarea optiunii "Am preturi cu moneda de referinta in valuta" din [Configurare > Generale](https://cloud.smartbill.ro/documente/preferinte-generale/) in SmartBill Cloud. Seteaza `currency` la nivel de produs cu valuta contractului si `currency` la nivel de proforma cu moneda de emitere. `exchangeRate` pe produs este optional - daca nu e specificat, se foloseste cursul din [Preferinte personale](https://cloud.smartbill.ro/core/configurare/preferinte-personale/) (sectiunea "Curs valutar preluat de pe Internet": cursul de azi sau de ieri, cu adaos procentual optional).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "currency": "RON",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "price": 497,
              "measuringUnitName": "buc",
              "taxPercentage": 21,
              "currency": "EUR",
              "exchangeRate": 4.97
            }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>11. Emitere proforma cu CIF intracomunitar</strong></summary>

        Daca esti inregistrat in sistemul electronic One Stop Shop, intra in contul SmartBill la [Configurare > Date Firma](https://cloud.smartbill.ro/core/configurare/date-firma/) si completeaza campul `CIF intracomunitar`. Daca ai nevoie de CIF OSS, foloseste optiunea `Genereaza CIF OSS` afisata langa camp. Dupa configurare, seteaza `useIntraCif: true` pentru a emite proforma cu acest CIF.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "useIntraCif": true,
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Company GmbH",
            "vatCode": "DE123456789",
            "address": "Musterstrasse 1",
            "city": "Berlin",
            "county": "Berlin",
            "country": "Germania"
          },
          "products": [{ "name": "Servicii consultanta", "code": "SRV001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 0, "taxName": "Taxare inversa", "isService": true }]
        }
        ```

        </details>

        <details>
        <summary><strong>12. Emitere proforma - emitent neplatitor de TVA</strong></summary>

        Daca firma ta nu este platitoare de TVA, nu este necesar sa completezi campurile legate de TVA pe produse.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc" }]
        }
        ```

        </details>

        <details>
        <summary><strong>13. Emitere proforma cu cote TVA diferite</strong></summary>

        Adauga produse cu cote TVA diferite ca linii separate cu `taxPercentage` corespunzator - SmartBill grupeaza automat pe cote in document. La cota 0%, specifica intotdeauna si un `taxName` existent in cont, de exemplu `Taxare inversa`, `TVA Inclus`, `SDD` sau `SFDD` - fara el, API-ul alege implicit `Taxare inversa`, indiferent de regimul fiscal corect.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [
            { "name": "Produs standard", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 },
            { "name": "Aliment", "code": "PRD002", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 11 },
            { "name": "Produs scutit", "code": "PRD003", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 0, "taxName": "SDD" }
          ]
        }
        ```

        </details>

        <details>
        <summary><strong>14. Emitere proforma in limba straina</strong></summary>

        Proforma se emite implicit in limba romana (`RO`). Pentru emiterea intr-o alta limba, seteaza parametrul `language` la nivelul proformei.

        Poti folosi o limba predefinita in SmartBill Cloud sau o limba definita de administrator in cont. Valoarea trimisa in `language` trebuie sa corespunda unei limbi disponibile in cont.

        `language` controleaza limba documentului, dar denumirea produselor si unitatile de masura trebuie traduse explicit pe fiecare produs, prin `translatedName` si `translatedMeasuringUnit`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "language": "EN",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{
            "name": "Produs 1",
            "translatedName": "Product 1",
            "code": "PRD001",
            "quantity": 1,
            "price": 100,
            "measuringUnitName": "buc",
            "translatedMeasuringUnit": "piece",
            "taxPercentage": 21
          }]
        }
        ```

        </details>

        <details>
        <summary><strong>15. Emitere proforma cu observatii si mentiuni</strong></summary>

        Foloseste `observations` si `mentions` pentru textele afisate pe proforma.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_PROFORMEI",
          "issueDate": "2026-06-15",
          "client": { "name": "Client SRL", "vatCode": "RO22222222", "isTaxPayer": true, "address": "Str. Lalelei 1", "city": "Sector 1", "county": "Bucuresti", "country": "Romania", "email": "client@example.com" },
          "products": [{ "name": "Produs 1", "code": "PRD001", "quantity": 1, "price": 100, "measuringUnitName": "buc", "taxPercentage": 21 }],
          "observations": "Marfa se ridica de la sediu in termen de 5 zile lucratoare",
          "mentions": "Plata se face in contul IBAN specificat in contract"
        }
        ```

        </details>

        - --
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EstimateRequest'
            examples:
              proforma_simpla:
                summary: "1. Emitere proforma simpla"
                description: Campurile minime necesare pentru crearea unei proforme
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    country: Romania
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    measuringUnitName: buc
                    taxPercentage: 21
                    price: 10
              proforma_completa:
                summary: "2. Emitere proforma completa"
                description: Proforma cu toate campurile disponibile - client complet, delegat, emitent, produse cu discount si serviciu, observatii si mentiuni
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  isDraft: false
                  issueDate: '2026-06-15'
                  dueDate: '2026-07-15'
                  deliveryDate: '2026-06-20'
                  language: RO
                  currency: RON
                  precision: 2
                  useIntraCif: false
                  delegateName: Ion Popescu
                  delegateIdentityCard: AB 123456
                  delegateAuto: B-123-ABC
                  issuerCnp: '1234567890123'
                  issuerName: Maria Ionescu
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    code: CLI001
                    regCom: J40/1234/2020
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                    phone: '0722000000'
                    contact: Andrei Popa
                    iban: RO49AAAA1B31007593840000
                    bank: BCR
                    saveToDb: false
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    productDescription: Servicii de consultanta IT
                    translatedName: Consulting services
                    measuringUnitName: ora
                    translatedMeasuringUnit: hour
                    quantity: 1
                    price: 100
                    taxName: Normala
                    taxPercentage: 21
                    isService: true
                    saveToDb: false
                  - name: Discount valoric
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 1
                    discountValue: -10
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Produs 1
                    code: PRD001
                    quantity: 2
                    price: 200
                    measuringUnitName: buc
                    taxName: Normala
                    taxPercentage: 21
                    isService: false
                    saveToDb: false
                  - name: Discount procentual 10%
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 2
                    discountPercentage: 10
                    measuringUnitName: buc
                    taxPercentage: 21
                  paymentUrl: ''
                  sendEmail: false
                  email:
                    to: client@example.com
                    cc: ''
                    bcc: ''
                  observations: Marfa se ridica de la sediu in termen de 5 zile lucratoare
                  mentions: Plata se face in contul IBAN specificat in contract
              cu_link_plata:
                summary: "3. Emitere proforma cu link de plata"
                description: Genereaza proforma cu link de plata online pentru client
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  paymentUrl: Generate URL
              cu_ciorna:
                summary: "4. Emitere proforma ciorna (draft)"
                description: Creeaza proforma ca ciorna - fara numar atribuit pana la finalizare
                value:
                  companyVatCode: CIF_FIRMA
                  isDraft: true
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              cu_discounturi:
                summary: "5. Emitere proforma cu discounturi"
                description: Include discount valoric si discount procentual in acelasi payload
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Discount valoric
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 1
                    discountValue: -10
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Produs 2
                    code: PRD002
                    quantity: 1
                    price: 200
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Discount procentual 10%
                    isDiscount: true
                    numberOfItems: 1
                    discountType: 2
                    discountPercentage: 10
                    measuringUnitName: buc
                    taxPercentage: 21
              cu_servicii:
                summary: "6. Emitere proforma cu servicii"
                description: Foloseste isService pentru linii de serviciu
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    quantity: 1
                    price: 100
                    measuringUnitName: ora
                    taxPercentage: 21
                    isService: true
              cu_data_scadenta:
                summary: "7. Emitere proforma cu data scadenta"
                description: Seteaza dueDate pentru data scadenta
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  dueDate: '2026-07-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              cu_email:
                summary: "8. Emitere proforma cu trimitere pe email"
                description: Creeaza proforma si o trimite clientului prin email
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  sendEmail: true
                  email:
                    to: client@example.com
                    cc: ''
                    bcc: ''
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
              in_valuta:
                summary: "9. Emitere proforma in valuta"
                description: Creeaza proforma in EUR cu curs de schimb
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  currency: EUR
                  exchangeRate: 4.97
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                    currency: EUR
              pret_referinta_valuta:
                summary: "10. Emitere proforma cu pret referinta in valuta"
                description: Proforma in RON cu produse al caror pret de referinta este in valuta straina
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  currency: RON
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 497
                    measuringUnitName: buc
                    taxPercentage: 21
                    currency: EUR
                    exchangeRate: 4.97
              cif_intracomunitar:
                summary: "11. Emitere proforma cu CIF intracomunitar"
                description: Emitere pentru client din UE cu cod TVA intracomunitar
                value:
                  companyVatCode: CIF_FIRMA
                  useIntraCif: true
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Company GmbH
                    vatCode: DE123456789
                    address: "Musterstrasse 1"
                    city: Berlin
                    county: Berlin
                    country: Germania
                  products:
                  - name: Servicii consultanta
                    code: SRV001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 0
                    taxName: Taxare inversa
                    isService: true
              emitent_neplatitor_tva:
                summary: "12. Emitere proforma - emitent neplatitor de TVA"
                description: Emitere proforma fara TVA pe produse
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
              cote_tva_diferite:
                summary: "13. Emitere proforma cu cote TVA diferite"
                description: Proforma cu produse la cote TVA diferite
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs standard
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  - name: Aliment
                    code: PRD002
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 11
                  - name: Produs scutit
                    code: PRD003
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 0
                    taxName: SDD
              limba_straina:
                summary: "14. Emitere proforma in limba straina"
                description: Proforma emisa intr-o alta limba
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  language: EN
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    translatedName: Product 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    translatedMeasuringUnit: piece
                    taxPercentage: 21
              observatii_mentiuni:
                summary: "15. Emitere proforma cu observatii si mentiuni"
                description: Adauga observatii si mentiuni pe proforma
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  issueDate: '2026-06-15'
                  client:
                    name: Client SRL
                    vatCode: RO22222222
                    isTaxPayer: true
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    email: client@example.com
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    price: 100
                    measuringUnitName: buc
                    taxPercentage: 21
                  observations: Marfa se ridica de la sediu in termen de 5 zile lucratoare
                  mentions: Plata se face in contul IBAN specificat in contract
      responses:
        '200':
          description: Raspuns V1. `errorText` gol inseamna succes; `errorText` completat inseamna eroare functionala.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EstimateResponseV2'
              examples:
                success:
                  summary: Proforma creata cu succes
                  value:
                    errorText: ''
                    message: ''
                    number: '0001'
                    series: PRO
                    url: ''
                    documentUrl: https://cloud.smartbill.ro/documente/editare/proforma/12345/
                    documentId: 12345
                    documentViewUrl: https://cloud.smartbill.ro/documente/extern/pf/proforma/a1b2c3...?srvid=2
        '400':
          description: |
            Eroare functionala V1. Toate erorile 400 au aceeasi forma (`errorText` + envelope-ul standard). Exemplele de mai jos arata doar forma raspunsului; lista completa de mesaje si cum le rezolvi e in tabelele din descrierea endpoint-ului (sectiunea "Ai primit o eroare...").
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_series:
                  summary: seriesName
                  value:
                    errorText: "Seria nu a fost gasita! Folositi o serie creata in contul de cloud."
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
                client_name_empty:
                  summary: client.name
                  value:
                    errorText: "Client invalid!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
                products_empty:
                  summary: products
                  value:
                    errorText: "estimateProducts trebuie specificat si trebuie sa contina cel putin un element"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
        '410':
          description: Limita document depasita
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                too_many_lines:
                  summary: products[]
                  value:
                    errorText: "Numarul maxim acceptat de 400 intrari pe document a fost depasit."
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: -1
                    documentViewUrl: ''
        '500':
          description: Eroare interna V1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                company_vat_code_null:
                  summary: companyVatCode
                  value:
                    errorText: "Internal Server Error!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    documentUrl: ''
                    documentId: null
                    documentViewUrl: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate/pdf:
    get:
      tags:
      - Proforme
      summary: Descarcare proforma PDF
      operationId: getEstimatePdf
      security:
      - basicAuth: []
      description: |
        Descarca proforma in format PDF. Parametrii se trimit in URL (query string).

        Proforma poate fi preluata prin API doar ca fisier PDF. Nu exista endpoint pentru proforma in format JSON sau XML.

        Raspunsul de succes este un fisier binar (`application/octet-stream`), trimis cu `Content-Disposition: attachment`. Numele fisierului incepe cu `factura` chiar si pentru proforme - de exemplu `facturapro0271.pdf`.

        `Content-Type` din raspuns oglindeste header-ul `Accept` trimis in cerere: daca ceri `Accept: application/json`, raspunsul e etichetat `application/json`, desi corpul ramane acelasi PDF. Nu te baza pe `Content-Type` ca sa decizi cum tratezi raspunsul.

        **Nu trimite `Accept: application/pdf`.** Valoarea cea mai naturala e singura care nu merge: raspunsul e `406` cu `{"code": "invalid_accept_header"}`, nu PDF-ul. Merg `application/octet-stream`, `*/*`, `application/json` sau lipsa completa a header-ului `Accept`.

        **Ai primit o eroare la descarcare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice descarcarii.

        <details>
        <summary><strong>Erori la descarcarea PDF-ului</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul proformei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul proformei, de exemplu `number=0227`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria proformei trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria proformei, de exemplu `seriesname=pro`.</td>
            </tr>
            <tr>
              <td>Proforma nu exista</td>
              <td><code>Proforma cu seria si numarul pro99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Seria proformei
        schema:
          type: string
        example: SERIA_PROFORMEI
      - name: number
        in: query
        required: true
        description: Numarul proformei
        schema:
          type: string
        example: '0227'
      responses:
        '200':
          description: |
            Fisierul PDF al proformei, ca flux binar (`application/octet-stream`). Salveaza-l intr-un fisier `.pdf`.
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul proformei trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria proformei trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                proforma_negasita:
                  summary: Proforma nu exista
                  value:
                    errorText: Proforma cu seria si numarul pro99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate/invoices:
    get:
      tags:
      - Proforme
      summary: Verificare facturare proforma
      operationId: getEstimateInvoices
      security:
      - basicAuth: []
      description: |
        Verifica daca o proforma a fost transformata in factura. Parametrii se trimit in URL (query string).

        Raspunsul contine:
        - `areInvoicesCreated` - `true` daca proforma a fost facturata, altfel `false`.
        - `invoices` - lista facturilor generate din proforma (`series`, `number`), prezenta cand `areInvoicesCreated` e `true`.

        **Facturile ciorna apar si ele in lista, cu `number` gol.** O factura salvata in ciorna nu are inca numar, deci intrarea arata ca `{"series": "API", "number": ""}`, iar `areInvoicesCreated` devine `true` chiar daca singura factura generata din proforma e o ciorna. Daca te interesau doar facturile emise, ignora intrarile cu `number` gol.

        **Cum interpretezi raspunsul**

        Verifica mai intai statusul HTTP, apoi `areInvoicesCreated`. Pe acest endpoint, `errorText` poate fi completat si la un raspuns `200`, cand proforma exista dar nu este inca facturata.

        - `200` + `areInvoicesCreated: true` - proforma a fost facturata.
        - `200` + `areInvoicesCreated: false` - proforma exista, dar nu a fost facturata.
        - `400` sau `410` - verifica eroarea returnata.

        **Ai primit o eroare la verificarea facturarii?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice acestui endpoint.

        <details>
        <summary><strong>Erori la verificarea facturarii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul proformei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul proformei, de exemplu `number=0226`.</td>
            </tr>
            <tr>
              <td>Proforma nu exista</td>
              <td><code>Proforma cu seria pro si numarul 99999999 nu a fost gasita.</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Seria proformei
        schema:
          type: string
        example: SERIA_PROFORMEI
      - name: number
        in: query
        required: true
        description: Numarul proformei
        schema:
          type: string
        example: '0226'
      responses:
        '200':
          description: |
            Proforma exista. Verifica `areInvoicesCreated` ca sa afli daca a fost facturata.
          content:
            application/json:
              schema:
                type: object
                properties:
                  errorText:
                    type: string
                  areInvoicesCreated:
                    type: boolean
                    description: true daca proforma a fost transformata in factura
                  invoices:
                    type: array
                    description: Facturile generate din proforma (prezent cand areInvoicesCreated e true)
                    items:
                      type: object
                      properties:
                        series:
                          type: string
                        number:
                          type: string
              examples:
                facturata:
                  summary: Proforma a fost facturata
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    areInvoicesCreated: true
                    invoices:
                    - series: SERIA_FACTURII
                      number: '3793'
                nefacturata:
                  summary: Proforma exista dar nu e facturata (errorText doar informativ)
                  value:
                    errorText: Proforma cu seria pro si numarul 0226 nu a fost facturata.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    areInvoicesCreated: false
        '400':
          description: Parametru lipsa in URL
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errorText: "Numarul proformei trebuie specificat in url in parametrul 'number'!"
                message: ''
                number: ''
                series: ''
                url: ''
                areInvoicesCreated: false
        '410':
          description: Proforma nu exista
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errorText: Proforma cu seria pro si numarul 99999999 nu a fost gasita.
                message: ''
                number: ''
                series: ''
                url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate/cancel:
    put:
      tags:
      - Proforme
      summary: Anulare proforma
      operationId: cancelEstimate
      security:
      - basicAuth: []
      description: |
        Anuleaza o proforma existenta. Proforma anulata poate fi restaurata ulterior. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la anulare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice anularii.

        <details>
        <summary><strong>Erori la anularea proformei</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul proformei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul proformei de anulat, de exemplu `number=0222`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria proformei trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria proformei, de exemplu `seriesname=pro`.</td>
            </tr>
            <tr>
              <td>Proforma de anulat nu exista</td>
              <td><code>Proforma cu seria si numarul pro99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
            <tr>
              <td>Proforma este deja anulata</td>
              <td><code>Proforma pro0222 este deja anulata.</code></td>
              <td>Nu este o eroare: raspunsul are `errorText` gol si proforma ramane anulata.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
      - name: seriesname
        in: query
        required: true
        schema:
          type: string
      - name: number
        in: query
        required: true
        schema:
          type: string
      responses:
        '200':
          description: |
            Proforma anulata cu succes. Daca proforma era deja anulata, raspunsul e tot `200` cu un mesaj informativ (anularea e idempotenta).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              examples:
                anulata:
                  summary: Proforma anulata cu succes
                  value:
                    errorText: ''
                    message: Proforma cu seria si numarul pro0222 a fost anulata cu succes.
                    number: ''
                    series: ''
                    url: ''
                deja_anulata:
                  summary: Proforma era deja anulata (idempotent)
                  value:
                    errorText: ''
                    message: Proforma pro0222 este deja anulata.
                    number: ''
                    series: ''
                    url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul proformei trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria proformei trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                proforma_negasita:
                  summary: Proforma nu exista
                  value:
                    errorText: Proforma cu seria si numarul pro99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate/restore:
    put:
      tags:
      - Proforme
      summary: Restaurare proforma anulata
      operationId: restoreEstimate
      security:
      - basicAuth: []
      description: |
        Restaureaza o proforma anulata anterior. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la restaurare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice restaurarii.

        <details>
        <summary><strong>Erori la restaurarea proformei</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul proformei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul proformei de restaurat, de exemplu `number=0223`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria proformei trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria proformei, de exemplu `seriesname=pro`.</td>
            </tr>
            <tr>
              <td>Proforma de restaurat nu exista</td>
              <td><code>Proforma cu seria si numarul pro99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
      - name: seriesname
        in: query
        required: true
        schema:
          type: string
      - name: number
        in: query
        required: true
        schema:
          type: string
      responses:
        '200':
          description: |
            Proforma restaurata cu succes. Daca proforma nu era anulata, raspunsul e tot `200` cu un mesaj informativ (restaurarea e idempotenta).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              examples:
                restaurata:
                  summary: Proforma restaurata cu succes
                  value:
                    errorText: ''
                    message: Proforma cu seria si numarul pro0223 a fost restaurata cu succes.
                    number: ''
                    series: ''
                    url: ''
                nu_necesita:
                  summary: Proforma nu era anulata (idempotent)
                  value:
                    errorText: ''
                    message: Proforma pro0224 nu necesita restaurare.
                    number: ''
                    series: ''
                    url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul proformei trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria proformei trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                proforma_negasita:
                  summary: Proforma nu exista
                  value:
                    errorText: Proforma cu seria si numarul pro99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /estimate:
    delete:
      tags:
      - Proforme
      summary: Stergere proforma
      operationId: deleteEstimate
      security:
      - basicAuth: []
      description: |
        Sterge definitiv o proforma. Parametrii se trimit in URL (query string).

        **Ai primit o eroare la stergere?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice stergerii.

        <details>
        <summary><strong>Erori la stergerea proformei</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul proformei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul proformei de sters, de exemplu `number=0225`.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria proformei trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria proformei, de exemplu `seriesname=pro`.</td>
            </tr>
            <tr>
              <td>Proforma de sters nu exista</td>
              <td><code>Proforma cu seria si numarul pro99999999 nu a fost gasita!</code></td>
              <td>Verifica `seriesname` si `number`. Combinatia serie plus numar trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
      - name: seriesname
        in: query
        required: true
        schema:
          type: string
      - name: number
        in: query
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Proforma stearsa cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                errorText: ''
                message: Proforma cu seria si numarul pro0225 a fost stearsa cu succes.
                number: ''
                series: ''
                url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul proformei trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria proformei trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                proforma_negasita:
                  summary: Proforma nu exista
                  value:
                    errorText: Proforma cu seria si numarul pro99999999 nu a fost gasita!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /payment:
    post:
      tags:
      - Incasari
      summary: Emitere incasare
      operationId: createPayment
      security:
      - basicAuth: []
      description: |
        Emite o incasare. Tipul incasarii (`type`) determina ce campuri sunt necesare si daca se genereaza un document numerotat.

        `Chitanta` si `Bon` genereaza documente numerotate - chitanta pe seria trimisa in `seriesName`, bonul fiscal pe casa de marcat configurata. Celelalte tipuri (`Card`, `Ordin plata` etc.) emit incasarea fara document separat.

        ## Emiterea unui bon fiscal

        Pentru bon fiscal trimite `type: Bon`. Inainte de primul apel trebuie sa existe o casa de marcat implicita configurata in contul de Cloud, la **Configurari > Case de marcat** - pe ea se emit bonurile. Configurarea se face per utilizator: casa de marcat trebuie configurata pentru utilizatorul cu care te autentifici.

        Exista doua moduri de a tipari bonul, alese prin campul `returnFiscalPrinterText`:

        **1. Tiparire din contul SmartBill** - `returnFiscalPrinterText: false` (implicit)

        Bonul este inserat in SmartBill prin API si se tipareste din contul SmartBill. Campul `message` din raspuns vine gol. Recomandat cand casa de marcat se afla in alta locatie fizica.

        **2. Tiparire directa pe casa de marcat** - `returnFiscalPrinterText: true`

        Raspunsul contine campul `message` cu continutul bonului codificat Base64. Continutul trebuie decodat si scris intr-un fisier cu numele si extensia configurate pentru casa de marcat (implicit `bon.inp`).

        La emiterea unui bon, raspunsul contine `id` (identificatorul unic al bonului, cu care poti prelua ulterior continutul prin `GET /payment/text`), `number` (la emiterea prin API vine `0` - numarul se aloca pe casa de marcat, la tiparire) si, in cazul al doilea, `message`.

        Modalitatea de plata se detaliaza prin campurile `receivedCash`, `receivedCard`, `receivedTicheteMasa` si celelalte campuri `received*`.

        Bonul fiscal se emite doar in lei: `currency` trebuie sa fie `RON` (valoarea implicita).

        Pe liniile de bon, trimite doar `taxPercentage` si **omite `taxName`**. Un cont poate avea mai multe cote cu acelasi procent, iar daca cea trimisa in `taxName` nu e configurata pe casa de marcat, apelul e respins. Fara `taxName`, serverul alege o cota configurata pe casa.

        Casa de marcat implicita este legata de **utilizator**, nu de firma: bonul se emite pe casa de marcat implicita a utilizatorului cu care se face apelul la API, chiar daca alt utilizator al aceleiasi firme are alta casa setata implicit. Cotele de TVA si metodele de plata se configureaza separat pe fiecare casa de marcat, iar un bon care foloseste o cota neconfigurata pe casa respectiva este respins.

        ## Discount pe bon fiscal

        Pe bon se pot acorda discounturi, ca linii separate cu `isDiscount: true`.

        Pentru a evita anumite limitari ale caselor de marcat (sau blocarea acestora), un discount care acopera mai multe produse se imparte in discounturi mai mici, cate unul pentru fiecare produs. Exemplu: pentru un bon cu 3 produse si un discount total aferent lor, discountul se imparte in 3 bucati, astfel incat bonul va avea 6 pozitii.

        Discountul poate fi procentual (`discountPercentage`) sau valoric (`discountValue`).

        La discountul valoric, `discountValue` se trimite negativ si se scade din totalul bonului ca valoare cu TVA. Linia de discount urmeaza aceeasi regula de preturi ca liniile de produs: cu `isTaxIncluded: true` sumele sunt cu TVA inclus, cu `false` sunt fara.

        Vezi exemplul **Bon fiscal cu discount valoric** din lista de exemple a request-ului.

        **Ai primit o eroare la emiterea incasarii?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `companyVatCode`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice emiterii incasarii.

        <details>
        <summary><strong>Erori la emiterea incasarii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Datele clientului lipsesc</td>
              <td><code>Datele clientului trebuie specificate. Ele se preiau din factura doar in cazul in care usePaymentDetails = true.</code></td>
              <td>Trimite obiectul `client` (nume + CIF), sau `useInvoiceDetails: true` ca sa preiei clientul din factura.</td>
            </tr>
            <tr>
              <td>Valoarea incasarii lipseste</td>
              <td><code>Valoarea incasarii trebuie specificata.</code></td>
              <td>Trimite `value` cu suma incasata, sau `useInvoiceDetails: true` ca sa o preiei din factura.</td>
            </tr>
            <tr>
              <td>Tipul incasarii lipseste</td>
              <td><code>Tipul incasarii trebuie specificat.</code></td>
              <td>Trimite `type`, de exemplu `Chitanta`, `Card` sau `Ordin plata`.</td>
            </tr>
            <tr>
              <td>CIF client diferit de cel de pe factura (la incasare legata de factura)</td>
              <td><code>Ciful clientului de pe factura fac3802 difera de ciful clientului incasarii!</code></td>
              <td>La incasare legata de factura, clientul trebuie sa aiba acelasi CIF ca cel de pe factura. Foloseste `useInvoiceDetails: true` ca sa eviti nepotrivirea.</td>
            </tr>
            <tr>
              <td>Tip de incasare invalid</td>
              <td><code>Tipul documentului nu a fost gasit pe server!</code></td>
              <td>Foloseste un `type` valid: `Chitanta`, `Bon`, `Card`, `Card online`, `Ordin plata`, `Cec`, `Bilet ordin`, `Mandat postal`, `Extras de cont`, `Ramburs` sau `Alta incasare`. Litera mare nu conteaza (`Cec`, `CEC` si `cec` merg la fel), dar spatiile in plus invalideaza valoarea.</td>
            </tr>
            <tr>
              <td>Seria chitantei nu exista in cont</td>
              <td><code>Seria nu a fost gasita! Folositi o serie creata in contul de cloud.</code></td>
              <td>Trimite in `seriesName` o serie de chitanta creata in contul SmartBill Cloud.</td>
            </tr>
            <tr>
              <td>Factura din <code>invoicesList</code> nu exista</td>
              <td><code>Factura nu a fost gasita!</code></td>
              <td>Verifica `seriesName` si `number` din `invoicesList` - factura trebuie sa existe in cont.</td>
            </tr>
            <tr>
              <td>Factura din <code>invoicesList</code> este anulata</td>
              <td><code>Factura API0059 este anulata, nu o puteti incasa. Restaurati intai factura sau emiteti incasarea independent de factura.</code></td>
              <td>Restaureaza factura cu [PUT /invoice/restore](#tag/facturi/PUT/invoice/restore), sau emite incasarea fara `invoicesList`, trimitand `client` si `value`.</td>
            </tr>
            <tr>
              <td>Factura este deja incasata integral sau stornata</td>
              <td><code>Factura este incasata sau stornata in totalitate.</code></td>
              <td>Verifica intai cu [GET /invoice/paymentstatus](#tag/facturi/GET/invoice/paymentstatus) cat mai e de incasat. O factura cu `unpaidAmount` zero nu mai accepta incasari.</td>
            </tr>
            <tr>
              <td>Bon fiscal pentru o firma neplatitoare de TVA, fara configurarea corespunzatoare a casei de marcat</td>
              <td><code>Configurarea casei de marcat pentru firma neplatitoare de TVA nu a fost facuta.</code></td>
              <td>Verifica in contul SmartBill Cloud, la `Configurari > Case de marcat`, ca modalitatile de incasare au ID-urile salvate pe casa de marcat, ca ID-urile cotelor TVA sunt completate la `Configurari > Cote TVA` si ca te autentifici cu utilizatorul pe care este configurata casa de marcat - configurarea se face per utilizator.</td>
            </tr>
            <tr>
              <td>Nu exista casa de marcat configurata pentru utilizatorul care face apelul</td>
              <td><code>Nu s-a gasit casa de marcat pentru userul x.</code></td>
              <td>Configureaza o casa de marcat in contul SmartBill Cloud, la `Configurari > Case de marcat`, pentru utilizatorul cu care te autentifici.</td>
            </tr>
            <tr>
              <td>Cota de TVA din liniile bonului nu e configurata pe casa de marcat implicita a utilizatorului</td>
              <td><code>Cota TVA Normala (21.00%) nu a fost configurata pentru casa de marcat selectata</code></td>
              <td>Cel mai simplu: omite `taxName` si trimite doar `taxPercentage` - serverul alege atunci o cota configurata pe casa. Altfel, configureaza cota trimisa in `taxName` pe casa de marcat, in contul SmartBill Cloud la `Configurari > Case de marcat`. Cotele se configureaza pe fiecare casa separat, iar casa implicita difera de la un utilizator la altul.</td>
            </tr>
            <tr>
              <td>Bon fiscal emis in alta moneda decat leul</td>
              <td><code>Bonurile fiscale pot fi emise doar in Lei!</code></td>
              <td>Trimite `currency: RON`, sau omite campul - `RON` este valoarea implicita.</td>
            </tr>
            <tr>
              <td>Bon fiscal cu metode de plata care nu sunt configurate pe casa de marcat</td>
              <td><code>Au fost inregistrate urmatoarele plati partiale cu metode de plata neconfigurate pe casa de marcat: Card: 10, Numerar: 5</code></td>
              <td>Verifica configurarile casei de marcat din contul SmartBill Cloud - fiecare metoda folosita in campurile `received*` trebuie sa fie configurata pe casa de marcat.</td>
            </tr>
          </tbody>
        </table>

        </details>

        - --

        ## Tipuri de incasare

        <details>
        <summary><strong>1. Card</strong></summary>

        Emite o incasare cu cardul. Nu necesita serie si nu genereaza document separat.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "value": 119,
          "type": "Card"
        }
        ```

        </details>

        <details>
        <summary><strong>2. Chitanta</strong></summary>

        Genereaza un document de chitanta cu numar din seria specificata. Necesita `seriesName` si `isCash: true`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_CHITANTEI",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "value": 119,
          "text": "Plata factura",
          "type": "Chitanta",
          "isCash": true
        }
        ```

        </details>

        <details>
        <summary><strong>3. Chitanta ciorna (draft)</strong></summary>

        Salveaza chitanta ca ciorna - fara numar atribuit pana la finalizare din interfata SmartBill Cloud. Functioneaza doar pentru tipul `Chitanta`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_CHITANTEI",
          "issueDate": "2026-06-15",
          "isDraft": true,
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "value": 119,
          "text": "Plata factura",
          "type": "Chitanta",
          "isCash": true
        }
        ```

        </details>

        <details>
        <summary><strong>4. Bon fiscal</strong></summary>

        Emite un bon pe casa de marcat configurata implicit in contul de Cloud (**Configurari > Case de marcat**). Necesita `type: Bon` si liniile de produse in `products`.

        Campul `returnFiscalPrinterText` alege modul de tiparire:

        - `false` (implicit) - bonul se tipareste din contul SmartBill, iar campul `message` din raspuns vine gol. Recomandat cand casa de marcat se afla in alta locatie fizica.
        - `true` - raspunsul contine `message`, continutul bonului codificat Base64. Trebuie decodat si scris intr-un fisier cu numele si extensia configurate pentru casa de marcat (implicit `bon.inp`).

        Modalitatea de plata se detaliaza prin campurile `received*`. Bonul se emite doar in lei: `currency` trebuie sa fie `RON` (valoarea implicita).

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "products": [
            {
              "name": "Produs 1",
              "code": "PRD001",
              "quantity": 1,
              "measuringUnitName": "buc",
              "taxPercentage": 21,
              "price": 10
            }
          ],
          "value": 10,
          "type": "Bon",
          "returnFiscalPrinterText": true,
          "receivedCash": 10
        }
        ```

        Raspunsul contine `id` (folosit ulterior la `GET /payment/text`), `number` si, cand `returnFiscalPrinterText` este `true`, `message`.

        </details>

        <details>
        <summary><strong>5. Ordin de plata</strong></summary>

        Emite o incasare prin ordin de plata. Nu necesita serie si nu genereaza document separat.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "value": 119,
          "text": "Plata factura",
          "type": "Ordin plata"
        }
        ```

        </details>

        <details>
        <summary><strong>6. Incasare legata de o factura</strong></summary>

        Asociaza incasarea cu una sau mai multe facturi existente prin `invoicesList`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "seriesName": "SERIA_CHITANTEI",
          "issueDate": "2026-06-15",
          "client": {
            "name": "Client SRL",
            "vatCode": "RO22222222",
            "address": "Str. Lalelei 1",
            "city": "Sector 1",
            "county": "Bucuresti",
            "country": "Romania"
          },
          "value": 119,
          "type": "Chitanta",
          "isCash": true,
          "invoicesList": [{ "seriesName": "SERIA_FACTURII", "number": "0025" }]
        }
        ```

        </details>

        <details>
        <summary><strong>7. Incasare cu preluare date din factura</strong></summary>

        Cu `useInvoiceDetails: true`, clientul si suma sunt preluate automat din factura - nu mai e nevoie sa le trimiti explicit.

        Doua lucruri de stiut:

        - **`value` nu e ignorat daca il trimiti oricum.** Pe o factura de 111 lei, o incasare cu `value: 50` inregistreaza 50 si lasa 61 de incasat. Asa se face o incasare partiala.
        - **`invoicesList` accepta mai multe facturi.** Un singur apel inregistreaza incasarea pe toate facturile din lista.

        O factura **anulata** nu poate fi incasata: apelul intoarce `400` cu `Factura <serie><numar> este anulata, nu o puteti incasa. Restaurati intai factura sau emiteti incasarea independent de factura.`. O factura deja incasata integral intoarce `400` cu `Factura este incasata sau stornata in totalitate.`.

        ```json
        {
          "companyVatCode": "CIF_FIRMA",
          "issueDate": "2026-06-15",
          "type": "Ordin plata",
          "useInvoiceDetails": true,
          "invoicesList": [{ "seriesName": "SERIA_FACTURII", "number": "0025" }]
        }
        ```

        </details>

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentRequest'
            examples:
              card:
                summary: Incasare cu card
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  value: 119
                  type: Card
              chitanta:
                summary: Incasare cu chitanta
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_CHITANTEI
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  value: 119
                  text: Plata factura
                  type: Chitanta
                  isCash: true
              chitanta_ciorna:
                summary: Chitanta ciorna (draft)
                description: Salveaza chitanta ca ciorna - fara numar atribuit pana la finalizare. Functioneaza doar pentru tipul Chitanta.
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_CHITANTEI
                  issueDate: '2026-06-15'
                  isDraft: true
                  client: *client_exemplu
                  value: 119
                  text: Plata factura
                  type: Chitanta
                  isCash: true
              bon_fiscal:
                summary: Bon fiscal - tiparire din contul SmartBill
                description: Bonul este inserat in SmartBill si se tipareste din contul SmartBill. Raspunsul nu contine campul message.
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    measuringUnitName: buc
                    taxPercentage: 21
                    price: 10
                  value: 10
                  type: Bon
                  returnFiscalPrinterText: false
                  receivedCash: 10
              bon_fiscal_casa_de_marcat:
                summary: Bon fiscal - tiparire directa pe casa de marcat
                description: Raspunsul contine campul message cu continutul bonului codificat Base64, de scris in fisierul configurat pentru casa de marcat (implicit bon.inp).
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    measuringUnitName: buc
                    taxPercentage: 21
                    price: 10
                  value: 10
                  type: Bon
                  returnFiscalPrinterText: true
                  receivedCard: 10
              bon_fiscal_discount:
                summary: Bon fiscal cu discount valoric
                description: Discount valoric pe bon, cu preturi care includ TVA. discountValue se trimite negativ si se scade din total.
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  products:
                  - name: Produs 1
                    code: PRD001
                    quantity: 1
                    measuringUnitName: buc
                    currency: RON
                    isTaxIncluded: true
                    taxPercentage: 21
                    price: 100
                  - name: Discount valoric pe un produs
                    isDiscount: true
                    discountType: 1
                    numberOfItems: 1
                    measuringUnitName: buc
                    currency: RON
                    isTaxIncluded: true
                    taxPercentage: 21
                    discountValue: -10
                  value: 90
                  type: Bon
                  returnFiscalPrinterText: false
                  receivedCash: 90
              ordin_plata:
                summary: 'Incasare fara document: Ordin plata, Card, Card online, CEC, Bilet ordin, Mandat postal, Extras de cont, Ramburs, Alta incasare'
                description: Acelasi payload pentru toate tipurile care nu genereaza document separat. Schimba doar `type`.
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  value: 119
                  text: Plata factura
                  type: Ordin plata
              pe_factura:
                summary: Incasare legata de o factura
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_CHITANTEI
                  issueDate: '2026-06-15'
                  client: *client_exemplu
                  value: 119
                  type: Chitanta
                  isCash: true
                  invoicesList:
                  - seriesName: SERIA_FACTURII
                    number: '0025'
              din_factura:
                summary: Incasare cu preluare date din factura
                description: Preia clientul si suma direct din factura - nu e nevoie sa trimiti client sau value.
                value:
                  companyVatCode: CIF_FIRMA
                  issueDate: '2026-06-15'
                  type: Ordin plata
                  useInvoiceDetails: true
                  invoicesList:
                  - seriesName: SERIA_FACTURII
                    number: '0025'
      responses:
        '200':
          description: |
            Incasare emisa. Campurile din raspuns depind de tipul incasarii: `Chitanta` intoarce `number` si `series`; `Bon` intoarce `id` si `number`, plus `message` cand `returnFiscalPrinterText` este `true`; celelalte tipuri nu genereaza document separat.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentResponse'
              examples:
                fara_document:
                  summary: Card / Ordin plata - fara document numerotat
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                chitanta:
                  summary: Chitanta - document numerotat creat
                  value:
                    errorText: ''
                    message: ''
                    number: '0003'
                    series: CH
                    url: ''
                bon_fiscal:
                  summary: Bon fiscal - tiparire din contul SmartBill
                  description: Campul message lipseste, pentru ca returnFiscalPrinterText a fost false.
                  value:
                    errorText: ''
                    id: '12345'
                    number: '12'
                bon_fiscal_casa_de_marcat:
                  summary: Bon fiscal - tiparire directa pe casa de marcat
                  description: Campul message contine continutul bonului codificat Base64, de decodat si scris in fisierul configurat pentru casa de marcat.
                  value:
                    errorText: ''
                    id: '12345'
                    message: UCwxLF9fX19fXyxfLF9fO0NpZiBjbGllbnQ6Ozs7OzsNClAsMSxfX19fX18sXyxfXztSTzEyMzQ1Njc4Ozs7OzsNClMsMSxfX19fX18sXyxfXztjY2QxIE1hcGEgQTQ7NDAuMDA7Mi4wMDA7MTsxOzI7MDswOw0KUCwxLF9fX19fXyxfLF9fO2NjZDEgTWFwYSBBNDs7Ozs7DQpTLDEsX19fX19fLF8sX187Y2NkMiBCaWJsaW9yYWZ0IFBsYTs2MC4wMDszLjAwMDsxOzE7MjswOzA7DQpQLDEsX19fX19fLF8sX187Y2NkMiBCaWJsaW9yYWZ0IFBsYXN0aWZpYXQ7Ozs7Ow0KVCwxLF9fX19fXyxfLF9fOzE7NjAuMDA7Ozs7DQpULDEsX19fX19fLF8sX187DQo=
                    number: '12'
        '400':
          description: Campuri obligatorii lipsa (client, valoare, tip incasare) sau configurare lipsa a casei de marcat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                client_lipsa:
                  summary: Date client lipsa
                  value:
                    errorText: Datele clientului trebuie specificate. Ele se preiau din factura doar in cazul in care usePaymentDetails = true.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                valoare_lipsa:
                  summary: Valoarea incasarii lipsa
                  value:
                    errorText: Valoarea incasarii trebuie specificata.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                tip_lipsa:
                  summary: Tipul incasarii lipsa
                  value:
                    errorText: Tipul incasarii trebuie specificat.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                cif_client_diferit:
                  summary: CIF client difera de cel de pe factura (la incasare legata de factura)
                  value:
                    errorText: Ciful clientului de pe factura fac3802 difera de ciful clientului incasarii!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                casa_marcat_neconfigurata:
                  summary: Casa de marcat neconfigurata pentru firma neplatitoare de TVA (la bon fiscal)
                  description: "Apare la `type: Bon` cand firma nu este platitoare de TVA si casa de marcat nu are configurarea corespunzatoare in contul SmartBill Cloud."
                  value:
                    errorText: Configurarea casei de marcat pentru firma neplatitoare de TVA nu a fost facuta.
                    message: ''
                    number: '169'
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/ServerError'
  /tax:
    get:
      tags:
      - Configurari
      summary: Cote TVA si serii
      operationId: getTaxAndSeries
      security:
      - basicAuth: []
      description: |
        Returneaza cotele de TVA configurate in contul SmartBill. Foloseste `name`-ul unei cote in campul `taxName` la emiterea documentelor.

        > Endpoint-ul returneaza doar cotele de TVA (`taxes`). Seriile de documente se obtin din [Serii de documente](#tag/configurari/GET/series), nu de aici.
        >
        > Valorile depind de ce e configurat in cont. Cotele standard din Romania (2026) sunt `21` (Normala) si `11` (Redusa); cotele `19`, `9` si `5` nu mai exista in lege.

        Endpointul nu are erori proprii: singurele erori posibile sunt cele comune tuturor endpoint-urilor V1 - email/token, `cif`, drepturi pe firma. Vezi [Erori API V1](#api-1/description/erori-api-v1).
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      responses:
        '200':
          description: Cotele de TVA configurate in cont
          content:
            application/json:
              schema:
                type: object
                properties:
                  errorText:
                    type: string
                  taxes:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        percentage:
                          type: number
              example:
                errorText: ''
                message: ''
                number: ''
                series: ''
                url: ''
                taxes:
                - name: Normala
                  percentage: 21
                - name: Redusa
                  percentage: 11
                - name: Taxare inversa
                  percentage: 0
        '401':
          $ref: '#/components/responses/Unauthorized'
  /series:
    get:
      tags:
      - Configurari
      summary: Serii de documente
      operationId: getSeries
      security:
      - basicAuth: []
      description: |
        Returneaza informatii despre seriile de documente configurate in SmartBill.

        **Tipuri de serii:**
        - `f` - serii de facturi
        - `p` - serii de proforme
        - `c` - serii de chitante

        Daca nu specifici `type`, sunt returnate toate seriile.

        **Ai primit o eroare?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar eroarea specifica.

        <details>
        <summary><strong>Erori la listarea seriilor</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>type</code> invalid</td>
              <td><code>Tipul documentului nu poate fi x! Parametrul type poate lua valorile: 'f' pentru factura, 'p' pentru proforma si 'c' pentru chitanta.</code></td>
              <td>Foloseste `type` doar cu `f` (factura), `p` (proforma) sau `c` (chitanta), sau omite-l ca sa primesti toate seriile.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: type
        in: query
        required: false
        description: Filtreaza dupa tipul seriei (f=factura, p=proforma, c=chitanta). Fara type, intoarce toate seriile.
        schema:
          type: string
          enum:
          - f
          - p
          - c
        example: f
      responses:
        '200':
          description: Lista seriilor configurate (fiecare cu `nextNumber` - urmatorul numar disponibil)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SeriesResponse'
              examples:
                all_series:
                  summary: Toate seriile (fara type)
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    list:
                    - name: fac
                      nextNumber: 3821
                      type: f
                    - name: pro
                      nextNumber: 227
                      type: p
                    - name: CH
                      nextNumber: 7
                      type: c
                invoice_series:
                  summary: Doar serii de factura (type=f)
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    list:
                    - name: fac
                      nextNumber: 3821
                      type: f
        '400':
          description: Tip de serie invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errorText: "Tipul documentului nu poate fi x! Parametrul type poate lua valorile: 'f' pentru factura, 'p' pentru proforma si 'c' pentru chitanta."
                message: ''
                number: ''
                series: ''
                url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /stocks:
    get:
      tags:
      - Stocuri
      summary: Listare stocuri
      operationId: getStocks
      security:
      - basicAuth: []
      description: |
        Returneaza informatii despre stocurile produselor din gestiuni.

        **Flexibilitate in interogare:**
        - **Fara filtre**: toate produsele din toate gestiunile
        - **Doar gestiune** (`warehouseName`): toate produsele din acea gestiune
        - **Doar produs** (`productName`/`productCode`): stocul acelui produs in toate gestiunile
        - **Ambele**: stocul unui produs anume intr-o gestiune anume

        **Structura raspunsului:**
        Returneaza informatii despre gestiune si detalii de produs:
        - numele si tipul gestiunii (en gros/en detail)
        - numele, codul, unitatea de masura si cantitatea in stoc a produsului

        **Ai primit o eroare la interogarea stocului?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice.

        <details>
        <summary><strong>Erori la interogarea stocului</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>date</code> lipseste</td>
              <td><code>Data la care vreti sa aflati valoarea stocului trebuie specificata!</code></td>
              <td>Trimite `date` in format `yyyy-MM-dd`. Este parametru obligatoriu.</td>
            </tr>
            <tr>
              <td><code>date</code> in format gresit</td>
              <td><code>Data trebuie sa fie de forma yyyy-MM-dd.</code></td>
              <td>Foloseste formatul `yyyy-MM-dd`, de exemplu `2026-07-11`.</td>
            </tr>
            <tr>
              <td>Gestiune inexistenta</td>
              <td><code>Gestiunea DepozitInexistent nu a fost gasita pe server.</code></td>
              <td>Verifica `warehouseName` - e case-sensitive si trebuie sa existe in cont.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        description: CIF-ul firmei tale
        schema:
          type: string
        example: CIF_FIRMA
      - name: date
        in: query
        required: true
        description: Data la care vrei stocul (format yyyy-MM-dd)
        schema:
          type: string
          format: date
        example: '2026-07-11'
      - name: warehouseName
        in: query
        required: false
        description: Filtreaza dupa numele gestiunii (atentie - case-sensitive)
        schema:
          type: string
        example: Depozit
      - name: productName
        in: query
        required: false
        description: Filtreaza dupa numele produsului
        schema:
          type: string
        example: Mere Golden
      - name: productCode
        in: query
        required: false
        description: Filtreaza dupa codul produsului (SKU)
        schema:
          type: string
        example: PRD004
      responses:
        '200':
          description: |
            Stocul pe gestiuni. Fiecare intrare are `warehouse` (nume + tip) si lista de `products` (`productName`, `productCode`, `measuringUnit`, `quantity`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StockResponse'
              examples:
                cu_stoc:
                  summary: Produse in gestiune
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    list:
                    - warehouse:
                        warehouseName: Depozit
                        warehouseType: en gros
                      products:
                      - productName: Mere Golden
                        productCode: PRD004
                        measuringUnit: buc
                        quantity: 8
                fara_stoc:
                  summary: Nu exista stoc pentru filtrele date
                  value:
                    errorText: ''
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                    list: []
        '400':
          description: Data lipsa/invalida sau gestiune inexistenta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                data_lipsa:
                  summary: Parametrul date lipsa
                  value:
                    errorText: Data la care vreti sa aflati valoarea stocului trebuie specificata!
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                data_format_gresit:
                  summary: Format data invalid
                  value:
                    errorText: Data trebuie sa fie de forma yyyy-MM-dd.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                gestiune_negasita:
                  summary: Gestiunea nu exista (atentie - case-sensitive)
                  value:
                    errorText: Gestiunea DepozitInexistent nu a fost gasita pe server.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /document/send:
    post:
      tags:
      - Email
      summary: Trimitere Document prin Email
      operationId: sendDocumentEmail
      security:
      - basicAuth: []
      description: |
        Trimite o factura sau o proforma catre client, pe email, ca atasament.

        **Cerinte**: trebuie sa ai configurat serverul de email in [SmartBill Cloud > Configurare > Email](https://cloud.smartbill.ro/core/configurare_mailuri/).

        **Variabile pentru textul emailului:**
        Parametrul `bodyText` accepta urmatorii marcatori:
        - `#tip document#` - tipul documentului (factura/proforma)
        - `#serie numar document#` - seria si numarul
        - `#link document#` - link catre document
        - `#data emiterii#` - data emiterii
        - `#data scadentei#` - data scadentei
        - `#total document#` - suma totala, cu moneda
        - `#mentiune#` - mentiunile documentului
        - `#nume client#` - numele clientului
        - `#persoana contact#` - persoana de contact

        **Nota**: atat `subject`, cat si `bodyText` trebuie codificate Base64.

        ## Ce e obligatoriu si ce are fallback

        Obligatorii sunt doar `companyVatCode`, `seriesName`, `number` si `type`. Restul au fallback:

        - `to` omis sau gol - emailul se trimite la adresa clientului de pe document;
        - `subject` sau `bodyText` omise - se foloseste sablonul configurat in contul SmartBill.

        Valoarea din `type` nu e sensibila la litere mari: `factura`, `Factura` si `FACTURA` sunt acceptate la fel. `type` selecteaza si tipul de document cautat - o proforma trimisa cu `type: factura` intoarce `Documentul nu a fost gasit`.

        ## Forma raspunsului

        Endpointul nu raspunde ca restul V1. Raspunsul are un obiect `status`, cu `code` si `message`:

        ```json
        { "status": { "code": 0, "message": "Documentul a fost trimis cu succes." } }
        ```

        `code` este `0` la succes si `1` la eroare. Nu exista camp `errorText` - un client care verifica doar `errorText` nu vede niciodata eroarea. Excepția: erorile de autentificare si de acces la firma vin in forma clasica V1, cu `errorText`, si cu status HTTP `401`.

        **Ai primit o eroare la trimiterea emailului?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `companyVatCode`, drepturi pe firma, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice acestui endpoint. Toate vin cu `status.code: 1`.

        <details>
        <summary><strong>Erori la trimiterea emailului</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Valoare neacceptata in <code>type</code></td>
              <td><code>Valoarea campului 'type' nu este suportata (invoice). Valorile acceptate sunt: factura, proforma.</code></td>
              <td>Trimite `factura` sau `proforma`. Variantele englezesti `invoice` si `estimate` nu sunt acceptate. Litera mare nu conteaza.</td>
            </tr>
            <tr>
              <td><code>type</code> lipsa sau gol</td>
              <td><code>type  trebuie specificat. Valorile acceptate sunt: factura, proforma.</code></td>
              <td>`type` e obligatoriu, spre deosebire de `to`, `subject` si `bodyText`.</td>
            </tr>
            <tr>
              <td>Documentul nu exista, sau <code>type</code> nu corespunde tipului lui</td>
              <td><code>Documentul nu a fost gasit</code></td>
              <td>Verifica `seriesName` si `number`. Apare si cand documentul exista, dar e trimis cu tipul greșit - o proforma cu `type: factura`, de exemplu.</td>
            </tr>
            <tr>
              <td><code>seriesName</code> gol</td>
              <td><code>Seria nu a fost gasita! Folositi o serie creata in contul de cloud.</code></td>
              <td>Trimite o serie existenta in contul SmartBill Cloud.</td>
            </tr>
            <tr>
              <td><code>number</code> gol</td>
              <td><code>Numarul documentului  trebuie specificat</code></td>
              <td>Trimite numarul documentului, ca text.</td>
            </tr>
            <tr>
              <td><code>subject</code> nu e codificat Base64</td>
              <td><code>Subiectul emailului trebuie sa fie codat folosind Base64.</code></td>
              <td>Codifica subiectul in Base64 inainte de trimitere.</td>
            </tr>
            <tr>
              <td><code>bodyText</code> nu e codificat Base64</td>
              <td><code>Continutul emailului trebuie sa fie codat folosind Base64.</code></td>
              <td>Codifica si corpul emailului in Base64.</td>
            </tr>
            <tr>
              <td>Adresa de email invalida, in <code>to</code>, <code>cc</code> sau <code>bcc</code></td>
              <td><code>Invalid Addresses</code>, <code>Missing domain</code>, <code>Missing local name</code>, <code>Domain contains illegal character</code></td>
              <td>Mesajul depinde de felul in care e ruptă adresa. La mai multi destinatari, una singura invalida respinge tot apelul.</td>
            </tr>
            <tr>
              <td>Serverul de email nu e configurat in cont</td>
              <td><code>Server-ul de email nu a fost configurat.</code></td>
              <td>Configureaza serverul de email in [SmartBill Cloud > Configurare > Email](https://cloud.smartbill.ro/core/configurare_mailuri/).</td>
            </tr>
          </tbody>
        </table>

        </details>
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendEmailRequest'
            examples:
              invoice:
                summary: Trimitere factura
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_FACTURII
                  number: '0025'
                  type: factura
                  to: client@example.com
                  cc: ''
                  bcc: ''
                  subject: RmFjdHVyYSBGQUMgMDAyNQ==
                  bodyText: QnVuYSB6aXVhLCBBdGFzYXQgdmEgdHJhbnNtaXRlbSBmYWN0dXJhLg==
              proforma:
                summary: Trimitere proforma
                value:
                  companyVatCode: CIF_FIRMA
                  seriesName: SERIA_PROFORMEI
                  number: '0001'
                  type: proforma
                  to: client@example.com
                  subject: UHJvZm9ybWEgUFJPIDAwMDE=
                  bodyText: QnVuYSB6aXVhLCBBdGFzYXQgdmEgdHJhbnNtaXRlbSBwcm9mb3JtYS4=
      responses:
        '200':
          description: Email trimis cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentSendResponse'
              example:
                status:
                  code: 0
                  message: Documentul a fost trimis cu succes.
        '400':
          description: Document negasit, parametru invalid sau server de email neconfigurat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentSendResponse'
              examples:
                tip_nesuportat:
                  summary: Valoare neacceptata in `type`
                  value:
                    status:
                      code: 1
                      message: 'Valoarea campului ''type'' nu este suportata (invoice). Valorile acceptate sunt: factura, proforma.'
                tip_lipsa:
                  summary: '`type` lipsa sau gol'
                  value:
                    status:
                      code: 1
                      message: 'type  trebuie specificat. Valorile acceptate sunt: factura, proforma.'
                document_negasit:
                  summary: Documentul nu exista in cont
                  value:
                    status:
                      code: 1
                      message: Documentul nu a fost gasit
                serie_lipsa:
                  summary: '`seriesName` gol'
                  value:
                    status:
                      code: 1
                      message: Seria nu a fost gasita! Folositi o serie creata in contul de cloud.
                numar_lipsa:
                  summary: '`number` gol'
                  value:
                    status:
                      code: 1
                      message: Numarul documentului  trebuie specificat
                subiect_necodificat:
                  summary: '`subject` nu e codificat Base64'
                  value:
                    status:
                      code: 1
                      message: Subiectul emailului trebuie sa fie codat folosind Base64.
                corp_necodificat:
                  summary: '`bodyText` nu e codificat Base64'
                  value:
                    status:
                      code: 1
                      message: Continutul emailului trebuie sa fie codat folosind Base64.
                adresa_invalida:
                  summary: Adresa de email invalida
                  value:
                    status:
                      code: 1
                      message: Invalid Addresses
                server_email_neconfigurat:
                  summary: Serverul de email nu e configurat in cont
                  value:
                    status:
                      code: 1
                      message: Server-ul de email nu a fost configurat.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/ServerError'
  /payment/text:
    get:
      tags:
      - Incasari
      summary: Preluare date bon fiscal
      operationId: getPaymentText
      security:
      - basicAuth: []
      description: |
        Preia continutul unui bon fiscal, codificat Base64, pentru trimitere la imprimanta fiscala.

        Endpoint specific bonurilor fiscale. Parametrul `id` este ID-ul intern al bonului fiscal, returnat la crearea acestuia. Incasarile obisnuite (`Chitanta`, `Card`, `Ordin plata`) nu intorc un astfel de `id`.

        Continutul depinde de casa de marcat setata ca implicita pentru utilizatorul care face apelul - nu de casa pe care s-a emis bonul. Consecinte:

        - acelasi `id` intoarce alt continut daca intre apeluri s-a schimbat casa implicita;
        - doi utilizatori cu case implicite diferite primesc formate diferite pentru acelasi bon;
        - daca pe casa implicita nu e configurata cota de TVA din liniile bonului, apelul intoarce `400`, desi bonul a fost emis cu succes.

        **Ai primit o eroare la preluarea datelor bonului fiscal?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice acestui endpoint.

        <details>
        <summary><strong>Erori la preluarea datelor bonului fiscal</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>id</code> invalid sau inexistent</td>
              <td><code>500</code> cu raspuns HTML</td>
              <td>Verifica faptul ca `id` provine din raspunsul de creare a unui bon fiscal.</td>
            </tr>
            <tr>
              <td>Cota de TVA din liniile bonului nu e configurata pe casa de marcat implicita din momentul apelului</td>
              <td><code>Cota TVA Normala2 (21.00%) nu a fost configurata pentru casa de marcat selectata</code></td>
              <td>Bonul e valid - doar generarea textului pentru casa curenta eșueaza. Configureaza cota pe casa de marcat implicita a utilizatorului care apeleaza, la `Configurari > Case de marcat`.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
        example: CIF_FIRMA
      - name: id
        in: query
        required: true
        description: ID-ul bonului fiscal (returnat la crearea acestuia)
        schema:
          type: integer
        example: 1384
      responses:
        '200':
          description: Continutul bonului fiscal, in `message`, codificat Base64
          content:
            application/json:
              schema:
                type: object
                properties:
                  errorText:
                    type: string
                  message:
                    type: string
                    description: Continutul bonului fiscal codificat Base64
              example:
                errorText: ''
                message: Qm9uIGZpc2NhbCBjb250ZW50Li4u
        '500':
          description: |
            `id` invalid sau inexistent. Verifica faptul ca `id`-ul provine de la crearea unui bon fiscal.
          content:
            text/html:
              schema:
                type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
  /payment/chitanta:
    delete:
      tags:
      - Incasari
      summary: Stergere chitanta
      operationId: deleteReceipt
      security:
      - basicAuth: []
      description: |
        Sterge o chitanta. Poate fi stearsa doar ultima chitanta din serie. Parametrii se trimit in URL (query string).

        Pentru incasari care nu sunt chitante (`Card`, `Ordin plata` etc.), foloseste [Stergere incasare](#tag/incasari/DELETE/payment/v2).

        **Ai primit o eroare la stergere?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice stergerii chitantei.

        <details>
        <summary><strong>Erori la stergerea chitantei</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Chitanta nu e ultima din serie</td>
              <td><code>Nu poti sterge documentul cu seria si numarul CH 0003, deoarece nu este ultimul din serie!</code></td>
              <td>Doar ultima chitanta din serie poate fi stearsa.</td>
            </tr>
            <tr>
              <td><code>number</code> lipseste din URL</td>
              <td><code>Numarul chitantei trebuie specificat in url in parametrul 'number'!</code></td>
              <td>Adauga `number` in query string cu numarul chitantei de sters.</td>
            </tr>
            <tr>
              <td><code>seriesname</code> lipseste din URL</td>
              <td><code>Seria chitantei trebuie specificata in url in parametrul 'seriesname'!</code></td>
              <td>Adauga `seriesname` in query string cu seria chitantei.</td>
            </tr>
            <tr>
              <td>Chitanta nu exista</td>
              <td><code>Chitanta nu a fost gasita.</code></td>
              <td>Verifica `seriesname` si `number`.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
        example: CIF_FIRMA
      - name: seriesname
        in: query
        required: true
        description: Seria chitantei
        schema:
          type: string
        example: CHT
      - name: number
        in: query
        required: true
        description: Numarul chitantei
        schema:
          type: string
        example: 0009
      responses:
        '200':
          description: Chitanta stearsa cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                errorText: ''
                message: Chitanta cu seria si numarul CH0006 a fost stearsa cu succes.
                number: ''
                series: ''
                url: ''
        '400':
          description: Parametru lipsa in URL sau document negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                numar_lipsa:
                  summary: Parametrul number lipsa
                  value:
                    errorText: "Numarul chitantei trebuie specificat in url in parametrul 'number'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                serie_lipsa:
                  summary: Parametrul seriesname lipsa
                  value:
                    errorText: "Seria chitantei trebuie specificata in url in parametrul 'seriesname'!"
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                chitanta_negasita:
                  summary: Chitanta nu exista
                  value:
                    errorText: Chitanta nu a fost gasita.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '403':
          description: Chitanta nu e ultima din serie
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errorText: Nu poti sterge documentul cu seria si numarul CH 0003, deoarece nu este ultimul din serie!
                message: ''
                number: ''
                series: ''
                url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /payment/v2:
    delete:
      tags:
      - Incasari
      summary: Stergere incasare
      operationId: deletePaymentV2
      security:
      - basicAuth: []
      description: |
        Sterge o incasare care nu este chitanta (`Card`, `CEC`, `Bilet ordin`, `Ordin plata`, `Mandat postal`, `Alta incasare`). Parametrii se trimit in URL (query string).

        Chitantele si bonurile fiscale nu se sterg de aici. Pentru chitante foloseste [Stergere chitanta](#tag/incasari/DELETE/payment/chitanta).

        Incasarea se identifica in doua moduri (pe langa `cif` si `paymentType`, mereu obligatorii):

        1. **Dupa factura**: `invoiceSeries` + `invoiceNumber`.
        2. **Dupa detaliile incasarii**: `paymentDate` + `paymentValue` + `clientName` + `clientCif`. Toate patru sunt necesare - cu unul singur dintre `clientName` si `clientCif` incasarea nu e gasita.

        Aici `paymentType` este **sensibil la litere mari**, spre deosebire de emiterea incasarii: pentru cec valoarea acceptata la stergere este `CEC`, nu `Cec`.

        `clientCif` trebuie sa fie exact valoarea stocata pe incasare. Daca clientul e platitor de TVA, CIF-ul e stocat cu prefixul `RO`, deci `RO22222222`, nu `22222222`.

        La succes raspunsul este `200` cu `errorText` gol.

        **Ai primit o eroare la stergere?**

        **Erorile de autentificare si autorizare sunt comune tuturor endpoint-urilor V1.** Pentru email/token, `cif`, drepturi pe firma sau pe serie, vezi [Erori API V1](#api-1/description/erori-api-v1). Mai jos gasesti doar erorile specifice stergerii incasarii.

        <details>
        <summary><strong>Erori la stergerea incasarii</strong></summary>

        <table>
          <thead>
            <tr>
              <th>Situatie</th>
              <th>Eroare</th>
              <th>Sugestie</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Nicio incasare nu corespunde datelor trimise</td>
              <td><code>Nu au fost gasite incasari conform datelor specificate.</code></td>
              <td>Verifica datele de identificare (factura sau data+valoare+client). Trebuie sa corespunda exact unei incasari existente.</td>
            </tr>
            <tr>
              <td><code>paymentType</code> este Chitanta (tip nepermis aici)</td>
              <td><code>Tipul incasarii (paymentType) poate fi 'Card', 'CEC', 'Bilet ordin', 'Ordin plata', 'Mandat postal', 'Alta incasare'.</code></td>
              <td>Chitantele se sterg prin [Stergere Chitanta](#tag/incasari/DELETE/payment/chitanta), nu prin acest endpoint.</td>
            </tr>
          </tbody>
        </table>

        </details>
      parameters:
      - name: cif
        in: query
        required: true
        schema:
          type: string
        example: CIF_FIRMA
      - name: paymentType
        in: query
        required: true
        description: 'Tipul incasarii de sters. Nu poate fi `Chitanta` sau `Bon fiscal`. Trebuie sa fie tipul incasarii existente pe factura: cu alt tip apelul intoarce `Nu au fost gasite incasari conform datelor specificate.`'
        schema:
          type: string
          enum:
          - Card
          - Card online
          - CEC
          - Bilet ordin
          - Ordin plata
          - Mandat postal
          - Extras de cont
          - Ramburs
          - Alta incasare
        example: Ordin plata
      - name: invoiceSeries
        in: query
        required: false
        description: Seria facturii, pentru stergere dupa factura
        schema:
          type: string
      - name: invoiceNumber
        in: query
        required: false
        description: Numarul facturii, pentru stergere dupa factura
        schema:
          type: string
      - name: paymentDate
        in: query
        required: false
        description: Data incasarii, pentru stergere dupa detaliile incasarii
        schema:
          type: string
          format: date
      - name: paymentValue
        in: query
        required: false
        description: Valoarea incasarii, pentru stergere dupa detaliile incasarii
        schema:
          type: number
      - name: clientName
        in: query
        required: false
        description: Numele clientului, pentru stergere dupa detaliile incasarii
        schema:
          type: string
      - name: clientCif
        in: query
        required: false
        description: CIF-ul clientului, pentru stergere dupa detaliile incasarii
        schema:
          type: string
      responses:
        '200':
          description: Incasare stearsa cu succes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                errorText: ''
                message: Incasarea emisa catre clientul Client Match SRL RO22222222 in data de 11/07/2026 cu valoare de 55 de tip Ordin plata a fost stearsa cu succes.
                number: ''
                series: ''
                url: ''
        '400':
          description: Incasare negasita sau tip nepermis
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                incasare_negasita:
                  summary: Nicio incasare nu corespunde datelor
                  value:
                    errorText: Nu au fost gasite incasari conform datelor specificate.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
                tip_nepermis:
                  summary: paymentType este Chitanta (nepermis aici)
                  value:
                    errorText: Tipul incasarii (paymentType) poate fi 'Card', 'CEC', 'Bilet ordin', 'Ordin plata', 'Mandat postal', 'Alta incasare'.
                    message: ''
                    number: ''
                    series: ''
                    url: ''
        '401':
          $ref: '#/components/responses/Unauthorized'
  /v3/companies/{cif}/suppliers:
    get:
      tags:
        - Furnizori
      summary: Listare furnizori
      operationId: listSuppliersV3
      security:
        - bearerAuth: []
      description: |
        Returneaza toti furnizorii din nomenclatorul tau SmartBill.

        **Filtrare**

        `name` potriveste oriunde in nume, nu doar la inceput: `?name=eta` gaseste `Furnizor Beta SRL`.

        `vatCode` nu normalizeaza prefixul: un furnizor salvat cu `RO33333333` nu e gasit de `?vatCode=33333333`. Trimite valoarea exact cum e salvata.

        Filtrele se combina cu AND: `?name=Beta&code=INEXISTENT` intoarce 0 rezultate. Un filtru trimis gol (`?name=`) e ignorat, deci primesti lista nefiltrata.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: name
          in: query
          schema:
            type: string
          description: Filtreaza dupa nume (potrivire partiala, case-insensitive)
          example: furnizor
        - name: code
          in: query
          schema:
            type: string
          description: Filtreaza dupa cod intern (potrivire exacta, case-sensitive)
          example: FURN002
        - name: vatCode
          in: query
          schema:
            type: string
          description: Filtreaza dupa CIF (potrivire exacta, case-insensitive)
          example: ro33333333
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: Numar maxim de rezultate returnate (intre 1 si 100)
          example: 2
        - name: after
          in: query
          schema:
            type: string
          description: Cursor pentru pagina urmatoare, id-ul furnizorului dupa care se continua. Nu se foloseste impreuna cu 'before'.
          example: sup_019f17cde03e70298e6070acc9ac0d08
        - name: before
          in: query
          schema:
            type: string
          description: Cursor pentru pagina anterioara, id-ul furnizorului inainte de care se continua. Nu se foloseste impreuna cu 'after'.
          example: sup_019f17cde03e7093a40f9a4b4fd30d09
      responses:
        '200':
          description: Lista furnizori paginata (paginare cursor)
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SupplierV3'
                  pagination:
                    type: object
                    properties:
                      next:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina urmatoare, sau null daca nu mai exista pagini
                      previous:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina anterioara, sau null daca esti pe prima pagina
              example:
                items:
                  - id: sup_019f17cde03d71b296bcfc67f5c30d07
                    name: Furnizor Alpha SRL
                    vatCode: "RO22222222"
                    regCom: J40/1234/2020
                    code: ""
                    address: Str. Plopilor 5
                    city: Bucuresti
                    county: Bucuresti
                    country: Romania
                    bank: ""
                    iban: ""
                    email: ""
                    contact: ""
                    phone: ""
                    isVatPayer: true
                  - id: sup_019f17cde03e70298e6070acc9ac0d08
                    name: Furnizor Beta SRL
                    vatCode: RO33333333
                    regCom: J12/5678/2019
                    code: FURN002
                    address: Str. Zorilor 12
                    city: Brasov
                    county: Brasov
                    country: Romania
                    bank: Banca Exemplu
                    iban: RO49AAAA1B31007593840000
                    email: supplier.beta@example.com
                    contact: Andrei Popa
                    phone: "0722000002"
                    isVatPayer: true
                pagination:
                  next: https://ws.smartbill.ro/SBORO/api/v3/companies/{cif}/suppliers?limit=2&after=sup_019f17cde03e70298e6070acc9ac0d08
                  previous: null
        '400':
          description: Parametri de paginare sau filtrare invalizi
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                limit_in_afara_intervalului:
                  summary: limit in afara intervalului 1-100
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/suppliers
                    errors:
                      - code: invalid_field_value
                        message: The 'limit' field must be between 1 and 100.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: limit
                before_si_after_impreuna:
                  summary: before si after folosite simultan
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/suppliers
                    errors:
                      - code: invalid_field_value
                        message: You can only use 'before' or 'after', not both at the same time.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: before
                cursor_malformat:
                  summary: cursor (before/after) cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/suppliers
                    errors:
                      - code: malformed_id
                        message: ID must start with sup_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/suppliers/{id}:
    get:
      tags:
        - Furnizori
      summary: Detalii furnizor
      operationId: getSupplierV3
      security:
        - bearerAuth: []
      description: Returneaza un singur furnizor din nomenclator, dupa id.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID-ul furnizorului
          example: sup_019f17cde03e7093a40f9a4b4fd30d14
      responses:
        '200':
          description: Detalii furnizor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierV3'
              example:
                id: "sup_019f17cde03e7093a40f9a4b4fd30d14"
                name: "Furnizor Exemplu SRL"
                vatCode: "RO44444444"
                regCom: "J40/9999/2021"
                code: "FURN003"
                address: "Str. Exemplu 10"
                city: "Bucuresti"
                county: "Bucuresti"
                country: "Romania"
                bank: "Banca Exemplu"
                iban: "RO49AAAA1B31007593840000"
                email: "supplier@example.com"
                contact: "Maria Ionescu"
                phone: "0722000003"
                isVatPayer: true
        '400':
          description: ID malformat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                prefix_gresit:
                  summary: ID cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/suppliers/cus_019f17cde03e7093a40f9a4b4fd30d14
                    errors:
                      - code: malformed_id
                        message: ID must start with sup_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
                format_invalid:
                  summary: ID cu format invalid (caractere non-hex)
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/suppliers/sup_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
                    errors:
                      - code: malformed_id
                        message: Invalid ID format
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '404':
          description: Furnizor negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              example:
                status: 404
                type: invalid_request_error
                instance: /SBORO/api/v3/companies/1234/suppliers/sup_019f17cde03e7093a40f9a4b4fd30d14
                errors:
                  - code: supplier_not_found
                    message: The supplier with id 'sup_019f17cde03e7093a40f9a4b4fd30d14' was not found.
                    docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/clients:
    get:
      tags:
        - Clienti
      summary: Listare clienti
      operationId: listClientsV3
      security:
        - bearerAuth: []
      description: |
        Returneaza toti clientii din nomenclatorul tau SmartBill.

        **Filtrare**

        `name` potriveste oriunde in nume, nu doar la inceput: `?name=lpha` gaseste `Client Alpha SRL`.

        `vatCode` nu normalizeaza prefixul: un client salvat cu `RO55555555` nu e gasit de `?vatCode=55555555`. Trimite valoarea exact cum e salvata.

        Filtrele se combina cu AND: `?name=Alpha&code=INEXISTENT` intoarce 0 rezultate. Un filtru trimis gol (`?name=`) e ignorat, deci primesti lista nefiltrata.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: name
          in: query
          schema:
            type: string
          description: Filtreaza dupa nume (potrivire partiala, case-insensitive)
          example: client
        - name: code
          in: query
          schema:
            type: string
          description: Filtreaza dupa cod intern (potrivire exacta, case-sensitive)
          example: CLI001
        - name: vatCode
          in: query
          schema:
            type: string
          description: Filtreaza dupa CIF (potrivire exacta, case-insensitive)
          example: ro55555555
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: Numar maxim de rezultate returnate (intre 1 si 100)
          example: 2
        - name: after
          in: query
          schema:
            type: string
          description: Cursor pentru pagina urmatoare, id-ul clientului dupa care se continua. Nu se foloseste impreuna cu 'before'.
          example: cus_019f17cde0937487bbe579c3d2d40d02
        - name: before
          in: query
          schema:
            type: string
          description: Cursor pentru pagina anterioara, id-ul clientului inainte de care se continua. Nu se foloseste impreuna cu 'after'.
          example: cus_019f17cde09d73a69826a35d9c640d03
      responses:
        '200':
          description: Lista clienti paginata (paginare cursor)
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ClientV3'
                  pagination:
                    type: object
                    properties:
                      next:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina urmatoare, sau null daca nu mai exista pagini
                      previous:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina anterioara, sau null daca esti pe prima pagina
              example:
                items:
                  - id: cus_019f17cde092765a8d30802230e90d01
                    name: Client Alpha SRL
                    vatCode: RO55555555
                    regCom: J40/1111/2018
                    code: CLI001
                    address: Str. Lalelei 1
                    city: Sector 1
                    county: Bucuresti
                    country: Romania
                    bank: Banca Exemplu
                    iban: RO49AAAA1B31007593840000
                    email: client@example.com
                    contact: Ion Popescu
                    phone: "0722000004"
                    isVatPayer: false
                    brand: ""
                    deliveryAddresses:
                      - description: Auto-generated address 1
                        address: Str. Salciilor 8
                        addressAdditionalInfo: ""
                        addressLine3: ""
                        city: Sector 1
                        county: Bucuresti
                        country: Romania
                        zipCode: ""
                        defaultAddress: true
                      - description: Auto-generated address 2
                        address: Str. Teilor 22
                        addressAdditionalInfo: ""
                        addressLine3: ""
                        city: Sector 1
                        county: Bucuresti
                        country: Romania
                        zipCode: ""
                        defaultAddress: false
                  - id: cus_019f17cde0937487bbe579c3d2d40d02
                    name: Client Beta SRL
                    vatCode: RO66666666
                    regCom: J12/2222/2017
                    code: CLI002
                    address: Str. Zorilor 12
                    city: Brasov
                    county: Brasov
                    country: Romania
                    bank: Banca Exemplu
                    iban: RO49AAAA1B31007593840000
                    email: client.beta@example.com
                    contact: Andrei Popa
                    phone: "0722000006"
                    isVatPayer: true
                    brand: ""
                    deliveryAddresses: []
                pagination:
                  next: https://ws.smartbill.ro/SBORO/api/v3/companies/{cif}/clients?limit=2&after=cus_019f17cde0937487bbe579c3d2d40d02
                  previous: null
        '400':
          description: Parametri de paginare sau filtrare invalizi
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                limit_in_afara_intervalului:
                  summary: limit in afara intervalului 1-100
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/clients
                    errors:
                      - code: invalid_field_value
                        message: The 'limit' field must be between 1 and 100.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: limit
                before_si_after_impreuna:
                  summary: before si after folosite simultan
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/clients
                    errors:
                      - code: invalid_field_value
                        message: You can only use 'before' or 'after', not both at the same time.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: before
                cursor_malformat:
                  summary: cursor (before/after) cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/clients
                    errors:
                      - code: malformed_id
                        message: ID must start with cus_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/clients/{id}:
    get:
      tags:
        - Clienti
      summary: Detalii client
      operationId: getClientV3
      security:
        - bearerAuth: []
      description: Returneaza un singur client din nomenclator, dupa id.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID-ul clientului
          example: cus_019f17cde09d73a69826a35d9c640d13
      responses:
        '200':
          description: Detalii client
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientV3'
              example:
                id: "cus_019f17cde09d73a69826a35d9c640d13"
                name: "Client Exemplu SRL"
                vatCode: "RO77777777"
                regCom: "J40/3333/2020"
                code: "CLI003"
                address: "Str. Exemplu 1"
                city: "Bucuresti"
                county: "Bucuresti"
                country: "Romania"
                bank: "Banca Exemplu"
                iban: "RO49AAAA1B31007593840000"
                email: "client@example.com"
                contact: "Elena Radu"
                phone: "0722000005"
                isVatPayer: false
                brand: ""
                deliveryAddresses:
                  - description: "Auto-generated address 1"
                    address: "Str. Livezilor 3"
                    addressAdditionalInfo: ""
                    addressLine3: ""
                    city: "Bucuresti"
                    county: "Bucuresti"
                    country: "Romania"
                    zipCode: ""
                    defaultAddress: true
                  - description: "Auto-generated address 2"
                    address: "Str. Digitala 7"
                    addressAdditionalInfo: ""
                    addressLine3: ""
                    city: "Bucuresti"
                    county: "Bucuresti"
                    country: "Romania"
                    zipCode: ""
                    defaultAddress: false
        '400':
          description: ID malformat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                prefix_gresit:
                  summary: ID cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/clients/ware_019f17cde09d73a69826a35d9c640d13
                    errors:
                      - code: malformed_id
                        message: ID must start with cus_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
                format_invalid:
                  summary: ID cu format invalid (caractere non-hex)
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/clients/cus_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
                    errors:
                      - code: malformed_id
                        message: Invalid ID format
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '404':
          description: Client negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              example:
                status: 404
                type: invalid_request_error
                instance: /SBORO/api/v3/companies/1234/clients/cus_019f17cde09d73a69826a35d9c640d13
                errors:
                  - code: client_not_found
                    message: The client with id 'cus_019f17cde09d73a69826a35d9c640d13' was not found.
                    docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/warehouses:
    get:
      tags:
        - Gestiuni
      summary: Listare gestiuni
      operationId: listWarehousesV3
      security:
        - bearerAuth: []
      description: |
        Returneaza toate gestiunile si depozitele din nomenclatorul tau SmartBill.

        **Filtrare**

        `name` potriveste oriunde in nume, nu doar la inceput: `?name=pozit` gaseste si `Depozit Central`, si `Depozit Secundar`. Un filtru trimis gol (`?name=`) e ignorat, deci primesti lista nefiltrata.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: name
          in: query
          schema:
            type: string
          description: Filtreaza dupa nume (potrivire partiala, case-insensitive)
          example: depozit
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: Numar maxim de rezultate returnate (intre 1 si 100)
          example: 2
        - name: after
          in: query
          schema:
            type: string
          description: Cursor pentru pagina urmatoare, id-ul gestiunii dupa care se continua. Nu se foloseste impreuna cu 'before'.
          example: ware_019f17cddf1272d59f06892d5b760d0b
        - name: before
          in: query
          schema:
            type: string
          description: Cursor pentru pagina anterioara, id-ul gestiunii inainte de care se continua. Nu se foloseste impreuna cu 'after'.
          example: ware_019f17cddf1272f2a7405cb6c7f30d0c
      responses:
        '200':
          description: Lista gestiuni paginata (paginare cursor)
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WarehouseV3'
                  pagination:
                    type: object
                    properties:
                      next:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina urmatoare, sau null daca nu mai exista pagini
                      previous:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina anterioara, sau null daca esti pe prima pagina
              example:
                items:
                  - id: ware_019f17cddf1272bc9730594516f70d0a
                    name: Depozit Central
                    description: Gestiune principala pentru marfa
                    type: en detail
                    keeper: Popescu Ion
                    address: Str. Depozitelor 1
                    city: New York
                    county: Cluj
                    country: US
                    isCustody: true
                  - id: ware_019f17cddf1272d59f06892d5b760d0b
                    name: Depozit Secundar
                    description: Gestiune pentru retur si marfa deteriorata
                    type: en gros
                    keeper: Popescu Ion
                    address: Str. Depozitelor 2
                    city: London
                    county: Brasov
                    country: GB
                    isCustody: false
                pagination:
                  next: https://ws.smartbill.ro/SBORO/api/v3/companies/{cif}/warehouses?limit=2&after=ware_019f17cddf1272d59f06892d5b760d0b
                  previous: null
        '400':
          description: Parametri de paginare sau filtrare invalizi
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                limit_in_afara_intervalului:
                  summary: limit in afara intervalului 1-100
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/warehouses
                    errors:
                      - code: invalid_field_value
                        message: The 'limit' field must be between 1 and 100.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: limit
                before_si_after_impreuna:
                  summary: before si after folosite simultan
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/warehouses
                    errors:
                      - code: invalid_field_value
                        message: You can only use 'before' or 'after', not both at the same time.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: before
                cursor_malformat:
                  summary: cursor (before/after) cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/warehouses
                    errors:
                      - code: malformed_id
                        message: ID must start with ware_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/warehouses/{id}:
    get:
      tags:
        - Gestiuni
      summary: Detalii gestiune
      operationId: getWarehouseV3
      security:
        - bearerAuth: []
      description: Returneaza o singura gestiune din nomenclator, dupa id.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID-ul gestiunii
          example: ware_019f17cddf1272f2a7405cb6c7f30d15
      responses:
        '200':
          description: Detalii gestiune
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WarehouseV3'
              example:
                id: "ware_019f17cddf1272f2a7405cb6c7f30d15"
                name: "Depozit Exemplu"
                description: "Gestiune de exemplu"
                type: "en gros"
                keeper: "Popescu Ion"
                address: "Str. Depozitelor 10"
                city: "Berlin"
                county: "Bucuresti"
                country: "DE"
                isCustody: false
        '400':
          description: ID malformat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                prefix_gresit:
                  summary: ID cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/warehouses/cus_019f17cddf1272f2a7405cb6c7f30d15
                    errors:
                      - code: malformed_id
                        message: ID must start with ware_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
                format_invalid:
                  summary: ID cu format invalid (caractere non-hex)
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/warehouses/ware_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
                    errors:
                      - code: malformed_id
                        message: Invalid ID format
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '404':
          description: Gestiune negasita
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              example:
                status: 404
                type: invalid_request_error
                instance: /SBORO/api/v3/companies/1234/warehouses/ware_019f17cddf1272f2a7405cb6c7f30d15
                errors:
                  - code: warehouse_not_found
                    message: The warehouse with id 'ware_019f17cddf1272f2a7405cb6c7f30d15' was not found.
                    docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/products:
    get:
      tags:
        - Produse
      summary: Listare produse si servicii
      operationId: listProductsV3
      security:
        - bearerAuth: []
      description: |
        Returneaza toate produsele si serviciile din nomenclatorul tau SmartBill. Le distingi dupa `isService`.

        **Filtrare**

        `name` potriveste cuvinte intregi, nu fragmente: `?name=Produs` gaseste `Produs 1`, dar `?name=rodus` nu gaseste nimic.

        Filtrele se combina cu AND: `?name=Produs&code=INEXISTENT` intoarce 0 rezultate. Un filtru trimis gol (`?name=`) e ignorat, deci primesti lista nefiltrata.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: name
          in: query
          schema:
            type: string
          description: Filtreaza dupa nume (potrivire pe cuvant, case-insensitive)
          example: produs
        - name: code
          in: query
          schema:
            type: string
          description: Filtreaza dupa cod intern (potrivire exacta, case-sensitive)
          example: PRD001
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          description: Numar maxim de rezultate returnate (intre 1 si 100)
          example: 2
        - name: after
          in: query
          schema:
            type: string
          description: Cursor pentru pagina urmatoare, id-ul produsului dupa care se continua. Nu se foloseste impreuna cu 'before'.
          example: prod_019f17cde0f37712b5cf1d43c39e0d05
        - name: before
          in: query
          schema:
            type: string
          description: Cursor pentru pagina anterioara, id-ul produsului inainte de care se continua. Nu se foloseste impreuna cu 'after'.
          example: prod_019f17cde0fd7625abd43bf960d10d06
      responses:
        '200':
          description: Lista produse paginata (paginare cursor)
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProductV3'
                  pagination:
                    type: object
                    properties:
                      next:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina urmatoare, sau null daca nu mai exista pagini
                      previous:
                        type: string
                        nullable: true
                        description: URL-ul complet catre pagina anterioara, sau null daca esti pe prima pagina
              example:
                items:
                  - id: prod_019f17cde0f276c9a8de73d769180d04
                    name: Servicii mentenanta
                    description: ""
                    code: ""
                    isService: true
                    price: 25.0
                    measuringUnitName: buc
                    currency: RON
                    vatPercentage: 21.0
                    vatName: Normala
                    isVatIncluded: true
                    cnCode: ""
                    cpvCode: "50700000"
                    countryOfOrigin: ""
                    containerDeposits: []
                  - id: prod_019f17cde0f37712b5cf1d43c39e0d05
                    name: Produs 1
                    description: ""
                    code: ""
                    isService: false
                    price: 32.0
                    measuringUnitName: buc
                    currency: RON
                    vatPercentage: 21.0
                    vatName: Normala
                    isVatIncluded: false
                    cnCode: ""
                    cpvCode: ""
                    countryOfOrigin: ""
                    containerDeposits: []
                pagination:
                  next: https://ws.smartbill.ro/SBORO/api/v3/companies/{cif}/products?limit=2&after=prod_019f17cde0f37712b5cf1d43c39e0d05
                  previous: null
        '400':
          description: Parametri de paginare sau filtrare invalizi
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                limit_in_afara_intervalului:
                  summary: limit in afara intervalului 1-100
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/products
                    errors:
                      - code: invalid_field_value
                        message: The 'limit' field must be between 1 and 100.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: limit
                before_si_after_impreuna:
                  summary: before si after folosite simultan
                  value:
                    status: 400
                    type: validation_error
                    instance: /SBORO/api/v3/companies/1234/products
                    errors:
                      - code: invalid_field_value
                        message: You can only use 'before' or 'after', not both at the same time.
                        docUrl: https://api.smartbill.ro/#v3-error-validation_error
                        param: before
                cursor_malformat:
                  summary: cursor (before/after) cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/products
                    errors:
                      - code: malformed_id
                        message: ID must start with prod_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
  /v3/companies/{cif}/products/{id}:
    get:
      tags:
        - Produse
      summary: Detalii produs
      operationId: getProductV3
      security:
        - bearerAuth: []
      description: Returneaza un singur produs sau serviciu din nomenclator, dupa id.
      parameters:
        - $ref: '#/components/parameters/CifPath'
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID-ul produsului
          example: prod_019f17cde0fd7625abd43bf960d10d16
      responses:
        '200':
          description: Detalii produs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductV3'
              example:
                id: "prod_019f17cde0fd7625abd43bf960d10d16"
                name: "Apa sticla 0.5 - AM001"
                description: "Descriere apa sticla 0.5"
                code: ""
                isService: false
                price: 2.0
                measuringUnitName: "sticla"
                currency: "RON"
                vatPercentage: 21.0
                vatName: "Normala"
                isVatIncluded: true
                cnCode: "22011011"
                cpvCode: "15981100"
                countryOfOrigin: ""
                containerDeposits:
                  - type: "Garantie SGR Plastic"
                    quantity: 1
        '400':
          description: ID malformat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              examples:
                prefix_gresit:
                  summary: ID cu prefix gresit
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/products/cus_019f17cde0fd7625abd43bf960d10d16
                    errors:
                      - code: malformed_id
                        message: ID must start with prod_
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
                format_invalid:
                  summary: ID cu format invalid (caractere non-hex)
                  value:
                    status: 400
                    type: invalid_request_error
                    instance: /SBORO/api/v3/companies/1234/products/prod_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
                    errors:
                      - code: malformed_id
                        message: Invalid ID format
                        docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '401':
          $ref: '#/components/responses/UnauthorizedV3'
        '403':
          $ref: '#/components/responses/ForbiddenV3'
        '404':
          description: Produs negasit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemResponseV3'
              example:
                status: 404
                type: invalid_request_error
                instance: /SBORO/api/v3/companies/1234/products/prod_019f17cde0fd7625abd43bf960d10d16
                errors:
                  - code: product_not_found
                    message: The product with id 'prod_019f17cde0fd7625abd43bf960d10d16' was not found.
                    docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
        '405':
          $ref: '#/components/responses/MethodNotAllowedV3'
        '406':
          $ref: '#/components/responses/NotAcceptableV3'
components:
  parameters:
    CifPath:
      name: cif
      in: path
      required: true
      schema:
        type: string
      description: CIF-ul firmei tale, fara spatii.
      example: CIF_FIRMA
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Email si token API din pagina [Integrari](https://cloud.smartbill.ro/core/integrari/).
    bearerAuth:
      type: http
      scheme: bearer
      description: Bearer token din pagina [Integrari](https://cloud.smartbill.ro/core/integrari/).
  schemas:
    UnauthorizedResponse:
      type: object
      properties:
        key:
          type: string
          example: "!.oresp@&"
        successfully:
          type: boolean
          example: false
        errorText:
          type: string
          example: Autentificare esuata. Va rugam verificati datele si incercati din nou.
        errorCode:
          type: string
          example: "0"
        message:
          type: string
          example: ''
        operationExecuted:
          type: boolean
          example: false
        cooldown:
          type: integer
          example: 0
        needsConsent:
          type: boolean
          example: false
    InvoiceRequest:
      type: object
      required:
      - companyVatCode
      - seriesName
      - client
      - products
      properties:
        companyVatCode:
          type: string
          description: CIF-ul firmei tale, exact ca in SmartBill Cloud.
          example: CIF_FIRMA
        seriesName:
          type: string
          description: Numele seriei de factura. Seria trebuie sa existe in SmartBill.
          example: SERIA_FACTURII
        issueDate:
          type: string
          format: date
          description: Data facturii, in format `YYYY-MM-DD`. Daca lipseste, se foloseste data curenta.
          example: '2026-06-15'
        dueDate:
          type: string
          format: date
          description: Data scadenta a facturii, in format `YYYY-MM-DD`.
          example: '2026-07-15'
        isDraft:
          type: boolean
          description: Creeaza factura ca ciorna, fara numar alocat pana la finalizarea manuala.
          default: false
        client:
          $ref: '#/components/schemas/Client'
          description: Datele clientului facturat.
        products:
          type: array
          description: Liniile de produse, servicii sau discount de pe factura.
          minItems: 1
          items:
            $ref: '#/components/schemas/Product'
        currency:
          type: string
          description: Codul monedei documentului
          x-description-en: Document currency code
          default: RON
          enum:
          - RON
          - EUR
          - USD
          - GBP
          - CAD
          - AUD
          - CHF
          - TRY
          - CZK
          - DKK
          - HUF
          - MDL
          - SEK
          - NOK
          - JPY
          - EGP
          - PLN
          - RUB
          - AED
          - BRL
          - CNY
          - HRK
          - INR
          - KRW
          - MXN
          - NZD
          - RSD
          - THB
          - UAH
          - XDR
          - ZAR
        exchangeRate:
          type: number
          description: Cursul valutar folosit pentru document. Daca lipseste, SmartBill foloseste cursul disponibil pentru moneda.
        precision:
          type: integer
          description: 'Numarul de zecimale folosit pentru sume. Valorile suportate sunt `2`, `3` si `4`. O valoare mai mare se limiteaza automat la `4`, fara eroare.'
          default: 2
        useStock:
          type: boolean
          description: 'Descarca stocul la emiterea facturii. Liniile de produs trebuie sa includa gestiunea potrivita. Modul de identificare a produsului depinde de setarea `Foloseste cod produs` din cont. Cand e activa, produsul se identifica **doar prin `code`**: unul care exista pe stoc nu e gasit dupa nume, iar apelul intoarce `Produsul ... nu are codul specificat.`. Cand e inactiva, se identifica **prin nume**, fara sensibilitate la litere mari. In ambele cazuri numele din nomenclator se rescrie cu cel trimis, chiar si cand `saveToDb` este `false` - `mere - 76` trimis pentru produsul `Mere - 76` il redenumeste. Unitatea de masura trebuie sa fie exact cea a produsului din nomenclator, iar `buc` si `BUC` sunt tratate diferit.'
          default: false
        payment:
          $ref: '#/components/schemas/InvoicePayment'
          description: Incasarea inregistrata odata cu emiterea facturii. Omite obiectul daca factura ramane neincasata.
        paymentDate:
          type: string
          format: date
          description: Data incasarii, in format `YYYY-MM-DD`.
        paymentUrl:
          type: string
          description: |
            Link de plata. Trimite `Generate URL` pentru generare automata prin procesatorul configurat in SmartBill
            sau trimite un URL propriu, de exemplu un link Stripe.
        sendEmail:
          type: boolean
          description: Trimite factura pe email dupa emitere.
          default: false
        email:
          type: object
          description: Destinatarii emailului, folositi cand `sendEmail` este `true`.
          properties:
            to:
              type: string
              description: Adresa destinatarului. Daca lipseste, se foloseste `client.email`.
            cc:
              type: string
              description: Adrese in copie.
            bcc:
              type: string
              description: Adrese in copie ascunsa.
        language:
          type: string
          description: 'Limba documentului. Valorile valide sunt limbile predefinite in SmartBill Cloud, plus cele definite in cont la `Configurare > Limbi`. O valoare necunoscuta nu e respinsa de server, dar documentul se emite in limba implicita. Pentru numele produsului si unitatea de masura in limba documentului, foloseste `translatedName` si `translatedMeasuringUnit` pe linia de produs.'
          default: RO
          enum:
          - RO
          - EN
          - DE
          - FR
          - IT
          - ES
        observations:
          type: string
          description: Observatii vizibile pe document
        mentions:
          type: string
          description: Mentiuni vizibile pe document
        deliveryDate:
          type: string
          format: date
          description: Data livrarii, in format `YYYY-MM-DD`.
        issuerName:
          type: string
          description: Numele emitentului
        issuerCnp:
          type: string
          description: CNP-ul emitentului (persoana fizica care emite factura)
        delegateName:
          type: string
          description: Numele delegatului
        delegateIdentityCard:
          type: string
          description: Seria si numarul cartii de identitate a delegatului
        delegateAuto:
          type: string
          description: Numarul de inmatriculare al autovehiculului delegatului
        aviz:
          type: string
          description: 'Numarul avizului de insotire a marfii, cand factura se emite pe baza unui aviz. Apare pe factura, in footer, sub forma `Nr aviz: <valoare>`.'
          x-description-en: 'Number of the delivery note, when the invoice is issued based on one. It appears on the invoice, in the footer, as `Nr aviz: <value>`.'
          example: AV-1908
        useIntraCif:
          type: boolean
          description: Foloseste codul TVA intracomunitar pentru client.
          default: false
        usePaymentTax:
          type: boolean
          description: Aplica TVA la incasare pentru factura.
          default: false
        paymentBase:
          type: number
          description: Baza incasata pentru TVA la incasare.
        colectedTax:
          type: number
          description: TVA incasata.
        paymentTotal:
          type: number
          description: Totalul incasat.
        useEstimateDetails:
          type: boolean
          description: Creeaza factura pe baza unei proforme existente.
          default: false
        estimate:
          type: object
          description: Proforma sursa, folosita cand `useEstimateDetails` este `true`.
          properties:
            seriesName:
              type: string
              description: Seria proformei sursa.
            number:
              type: string
              description: Numarul proformei sursa.
            useStock:
              type: boolean
              description: Descarca stocul la emiterea facturii generate din proforma.
    EstimateRequest:
      type: object
      required:
      - companyVatCode
      - seriesName
      - client
      - products
      properties:
        companyVatCode:
          type: string
          description: CIF-ul firmei tale, exact ca in SmartBill Cloud.
        seriesName:
          type: string
          description: Numele seriei de proforma. Seria trebuie sa existe in SmartBill.
        issueDate:
          type: string
          format: date
          description: Data proformei, in format `YYYY-MM-DD`. Daca lipseste, se foloseste data curenta.
        dueDate:
          type: string
          format: date
          description: Data scadenta a proformei, in format `YYYY-MM-DD`.
        isDraft:
          type: boolean
          description: Creeaza proforma ca ciorna, fara numar alocat pana la finalizarea manuala.
          default: false
        client:
          $ref: '#/components/schemas/Client'
          description: Datele clientului pentru care se emite proforma.
        products:
          type: array
          description: Liniile de produse, servicii sau discount de pe proforma.
          minItems: 1
          items:
            $ref: '#/components/schemas/Product'
        currency:
          type: string
          description: Codul monedei documentului
          x-description-en: Document currency code
          default: RON
          enum:
          - RON
          - EUR
          - USD
          - GBP
          - CAD
          - AUD
          - CHF
          - TRY
          - CZK
          - DKK
          - HUF
          - MDL
          - SEK
          - NOK
          - JPY
          - EGP
          - PLN
          - RUB
          - AED
          - BRL
          - CNY
          - HRK
          - INR
          - KRW
          - MXN
          - NZD
          - RSD
          - THB
          - UAH
          - XDR
          - ZAR
        exchangeRate:
          type: number
          description: Cursul valutar folosit pentru document. Daca lipseste, SmartBill foloseste cursul disponibil pentru moneda.
        paymentUrl:
          type: string
          description: Link de plata. Trimite `Generate URL` pentru generare automata prin procesatorul configurat in SmartBill sau trimite un URL propriu.
        sendEmail:
          type: boolean
          description: Trimite proforma pe email dupa emitere.
          default: false
        email:
          type: object
          description: Destinatarii emailului, folositi cand `sendEmail` este `true`.
          properties:
            to:
              type: string
              description: Adresa destinatarului. Daca lipseste, se foloseste `client.email`.
            cc:
              type: string
              description: Adrese in copie.
            bcc:
              type: string
              description: Adrese in copie ascunsa.
        language:
          type: string
          description: 'Limba documentului. Valorile valide sunt limbile predefinite in SmartBill Cloud, plus cele definite in cont la `Configurare > Limbi`. O valoare necunoscuta nu e respinsa de server, dar documentul se emite in limba implicita. Pentru numele produsului si unitatea de masura in limba documentului, foloseste `translatedName` si `translatedMeasuringUnit` pe linia de produs.'
          default: RO
        observations:
          type: string
          description: Observatii afisate pe proforma.
          example: Observatii pentru client
        mentions:
          type: string
          description: Mentiuni afisate pe proforma.
          example: Mentiuni suplimentare
        precision:
          type: integer
          description: 'Numarul de zecimale folosit pentru sume. Valorile suportate sunt `2`, `3` si `4`. O valoare mai mare se limiteaza automat la `4`, fara eroare.'
          x-description-en: 'Number of decimals used for amounts. The supported values are `2`, `3` and `4`. A larger value is automatically capped at `4`, without an error.'
          default: 2
        issuerName:
          type: string
          description: Numele emitentului.
          x-description-en: Issuer name.
        issuerCnp:
          type: string
          description: CNP-ul emitentului, cand pe proforma apare persoana fizica emitenta.
          x-description-en: Personal numeric code of the issuer, when the issuing person is shown on the estimate.
        delegateName:
          type: string
          description: Numele delegatului.
          x-description-en: Delegate name.
        delegateIdentityCard:
          type: string
          description: Seria si numarul cartii de identitate a delegatului.
          x-description-en: Delegate identity-card series and number.
        delegateAuto:
          type: string
          description: Numarul de inmatriculare al autovehiculului delegatului.
          x-description-en: Delegate vehicle registration number.
        useIntraCif:
          type: boolean
          description: Foloseste codul TVA intracomunitar pentru client.
          x-description-en: Use the intra-community VAT number for the client.
          default: false
        aviz:
          type: string
          description: 'Numarul avizului de insotire a marfii. Apare pe proforma, in footer, sub forma `Nr aviz: <valoare>`.'
          x-description-en: 'Number of the delivery note. It appears on the estimate, in the footer, as `Nr aviz: <value>`.'
          example: AV-1908
    PaymentRequest:
      type: object
      required:
      - companyVatCode
      - type
      properties:
        companyVatCode:
          type: string
          description: CIF-ul firmei tale, exact ca in SmartBill Cloud.
        type:
          type: string
          description: 'Tipul incasarii. Foloseste `Bon` pentru bon fiscal. Litera mare nu conteaza, dar spatiile in plus invalideaza valoarea.'
          x-description-en: 'Payment type. Use `Bon` for a fiscal receipt. Letter case does not matter, but extra spaces invalidate the value.'
          enum:
          - Card
          - Card online
          - Chitanta
          - Bon
          - Ordin plata
          - CEC
          - Bilet ordin
          - Mandat postal
          - Extras de cont
          - Ramburs
          - Alta incasare
        issueDate:
          type: string
          format: date
          description: Data incasarii, in format `YYYY-MM-DD`.
        isDraft:
          type: boolean
          description: Creeaza chitanta ca ciorna, daca tipul incasarii permite acest lucru.
          default: false
        seriesName:
          type: string
          description: Seria chitantei, obligatorie pentru incasari de tip `Chitanta`.
        number:
          type: string
          description: Numarul bonului fiscal. Daca lipseste, se aloca urmatorul numar disponibil de pe casa de marcat configurata. Se aplica doar incasarilor de tip `Bon`.
        returnFiscalPrinterText:
          type: boolean
          description: |
            Doar pentru `type: Bon`. Controleaza cum ajunge bonul la imprimanta fiscala. `true` returneaza continutul bonului in campul `message` al raspunsului, codificat Base64, pentru tiparire directa pe casa de marcat. `false` nu il returneaza, iar bonul se tipareste din contul SmartBill. Se ia in calcul casa de marcat configurata pentru utilizatorul care face apelul.
          default: false
        observation:
          type: string
          description: Alte observatii in legatura cu incasarea.
        useStock:
          type: boolean
          description: Opereaza stocul pentru produsele de pe bon.
          default: false
        client:
          $ref: '#/components/schemas/Client'
          description: Clientul pentru care se inregistreaza incasarea.
        products:
          type: array
          description: Liniile de produse sau servicii de pe bon. Se trimit la incasari de tip `Bon`.
          items:
            $ref: '#/components/schemas/Product'
        value:
          type: number
          description: Suma incasata.
        currency:
          type: string
          description: Moneda incasarii. Bonul fiscal poate fi emis doar in RON.
          default: RON
        exchangeRate:
          type: number
          description: Cursul valutar folosit pentru incasare.
          default: 1
        precision:
          type: integer
          description: 'Numarul de zecimale folosit pentru sume. Valorile suportate sunt `2`, `3` si `4`. O valoare mai mare se limiteaza automat la `4`, fara eroare.'
          default: 2
        isCash:
          type: boolean
          description: Marcheaza incasarea ca numerar.
          default: true
        receivedCash:
          type: number
          description: Valoarea achitata cu numerar. Modalitate de plata, folosita la incasari de tip `Bon`.
          default: 0
        receivedCard:
          type: number
          description: Valoarea achitata cu card.
          default: 0
        receivedTicheteMasa:
          type: number
          description: Valoarea achitata cu tichete de masa.
          default: 0
        receivedTicheteCadou:
          type: number
          description: Valoarea achitata cu tichete cadou.
          default: 0
        receivedOrdinDePlata:
          type: number
          description: Valoarea achitata cu ordin de plata.
          default: 0
        receivedCec:
          type: number
          description: Valoarea achitata cu cec.
          default: 0
        receivedCredit:
          type: number
          description: Valoarea achitata cu credit.
          default: 0
        receivedCupon:
          type: number
          description: Valoarea achitata cu cupoane.
          default: 0
        receivedPuncteDeFidelitate:
          type: number
          description: Valoarea achitata cu puncte de fidelitate.
          default: 0
        receivedBonuriValoareFixa:
          type: number
          description: Valoarea achitata cu bonuri cu valoare fixa.
          default: 0
        receivedMonedaAlternativa:
          type: number
          description: Valoarea achitata cu alta moneda.
          default: 0
        text:
          type: string
          description: Descrierea incasarii.
        translatedText:
          type: string
          description: Descrierea incasarii in limba documentului.
        language:
          type: string
          description: 'Limba documentului. Valorile valide sunt limbile predefinite in SmartBill Cloud, plus cele definite in cont la `Configurare > Limbi`. O valoare necunoscuta nu e respinsa de server, dar documentul se emite in limba implicita. Pentru numele produsului si unitatea de masura in limba documentului, foloseste `translatedName` si `translatedMeasuringUnit` pe linia de produs.'
          default: RO
        useInvoiceDetails:
          type: boolean
          description: 'Preia clientul si suma din factura indicata. Un `value` trimis explicit are prioritate si permite incasarea partiala.'
          x-description-en: 'Takes the client and the amount from the indicated invoice. A `value` sent explicitly takes precedence and allows a partial payment.'
          default: false
        invoicesList:
          description: Factura sau lista de facturi pentru care se inregistreaza incasarea. Lista poate contine mai multe facturi, iar un singur apel le acopera pe toate.
          x-description-en: Invoice or list of invoices for which the payment is recorded. The list can contain several invoices, and a single call covers all of them.
          oneOf:
          - type: array
            items:
              type: object
              properties:
                seriesName:
                  type: string
                  description: Seria facturii.
                number:
                  type: string
                  description: Numarul facturii.
          - type: object
            properties:
              seriesName:
                type: string
                description: Seria facturii.
              number:
                type: string
                description: Numarul facturii.
    Client:
      type: object
      required:
      - name
      - country
      properties:
        name:
          type: string
          description: Numele clientului, persoana juridica sau persoana fizica.
          example: Acme SRL
        vatCode:
          type: string
          description: Codul fiscal al clientului. Poate fi CUI/CIF romanesc sau cod TVA extern.
          example: RO22222222
        isTaxPayer:
          type: boolean
          description: 'Indica daca clientul este platitor de TVA. Implicit `false`: un client trimis fara acest camp se salveaza ca neplatitor.'
          default: false
        regCom:
          type: string
          description: Numarul de inregistrare la Registrul Comertului.
          example: J40/1234/2020
        address:
          type: string
          description: Adresa clientului.
          example: Str. Exemplu 1
        city:
          type: string
          description: 'Orasul clientului. Daca `county` este "Bucuresti", valoarea trebuie sa fie Sector 1 - Sector 6, altfel e-Factura nu se va valida in SPV.'
          example: Sector 1
        county:
          type: string
          description: Judetul clientului sau regiunea/statul pentru clienti externi.
          example: Bucuresti
        country:
          type: string
          description: Tara clientului. API-ul accepta text liber; recomandat este numele tarii sau codul uzual, de exemplu `Romania` sau `RO`.
          example: Romania
        email:
          type: string
          format: email
          description: Adresa de email a clientului.
          example: client@example.com
        phone:
          type: string
          description: Numarul de telefon al clientului.
        contact:
          type: string
          description: Persoana de contact
          x-description-en: Contact person name
        iban:
          type: string
          description: IBAN cont bancar
          x-description-en: Bank account IBAN
        bank:
          type: string
          description: Numele bancii
          x-description-en: Bank name
        code:
          type: string
          description: Codul intern al clientului in SmartBill
          x-description-en: Client internal code in SmartBill
        saveToDb:
          type: boolean
          description: Salveaza clientul in nomenclator daca e nou. Implicit `false`, deci clientul nu se salveaza daca nu ceri explicit - nici la descarcare de gestiune.
          x-description-en: Saves the client to the catalogue if new. Defaults to `false`, so the client is not saved unless you ask for it - not even with stock discharge.
          default: false
    Product:
      type: object
      required:
      - name
      - quantity
      - price
      - measuringUnitName
      - taxPercentage
      properties:
        name:
          type: string
          description: Numele produsului sau serviciului
          x-description-en: Product/service name
          example: Produs 1
        code:
          type: string
          description: |
            Codul produsului (SKU). **Obligatoriu daca firma ta are activata setarea "Foloseste cod produs"** in SmartBill Cloud, altfel optional.
          x-description-en: |
            Product code (SKU). **Required if your company has the "Foloseste cod produs" setting enabled** in SmartBill Cloud, otherwise optional.
        productDescription:
          type: string
          description: Descriere suplimentara produs
          x-description-en: Additional product description
        isService:
          type: boolean
          description: Este serviciu (nu produs fizic)
          x-description-en: Is this a service (not physical product)
          default: false
        quantity:
          type: number
          description: 'Cantitate. API-ul nu o valideaza: `0` si valorile negative sunt acceptate, iar documentul se emite fara eroare. Valideaza cantitatea in integrarea ta inainte de a trimite.'
          x-description-en: 'Quantity. The API does not validate it: `0` and negative values are accepted and the document is issued without an error. Validate the quantity in your integration before sending.'
          example: 1
        measuringUnitName:
          type: string
          description: Unitate de masura
          x-description-en: Unit of measure
          example: buc
        price:
          type: number
          minimum: 0
          description: Pret unitar
          x-description-en: Unit price
          example: 100
        currency:
          type: string
          description: Moneda pretului
          x-description-en: Price currency
          default: RON
          enum:
          - RON
          - EUR
          - USD
          - GBP
          - CAD
          - AUD
          - CHF
          - TRY
          - CZK
          - DKK
          - HUF
          - MDL
          - SEK
          - NOK
          - JPY
          - EGP
          - PLN
          - RUB
          - AED
          - BRL
          - CNY
          - HRK
          - INR
          - KRW
          - MXN
          - NZD
          - RSD
          - THB
          - UAH
          - XDR
          - ZAR
        exchangeRate:
          type: number
          description: Curs valutar pentru acest produs
          x-description-en: Exchange rate for this product
        isTaxIncluded:
          type: boolean
          description: Pretul include TVA. Implicit `false`, deci preturile sunt considerate fara TVA.
          x-description-en: Whether the price includes VAT. Defaults to `false`, so prices are treated as excluding VAT.
          default: false
        taxName:
          type: string
          description: Numele cotei TVA
          x-description-en: Tax name
          example: Normala
        taxPercentage:
          type: number
          description: Cota TVA a liniei. SmartBill accepta cotele existente in cont, inclusiv cote personalizate.
          x-description-en: VAT percentage rate. SmartBill accepts the VAT rates available in the account, including custom rates.
          example: 21
        warehouseName:
          type: string
          description: Numele gestiunii pentru descarcare stoc (case-sensitive!)
          x-description-en: Warehouse name for stock discharge (case-sensitive!)
        isDiscount:
          type: boolean
          description: Este linie de discount
          x-description-en: Is this a discount line
          default: false
        numberOfItems:
          type: integer
          description: 'Numarul de linii **imediat anterioare** la care se aplica discountul. **Obligatoriu pe o linie de discount**: fara el discountul e ignorat in silentiu, apelul intoarce `200`, iar documentul se emite cu totalul neredus.'
          x-description-en: 'Number of **immediately preceding** lines the discount applies to. **Required on a discount line**: without it the discount is silently ignored, the call returns `200`, and the document is issued with the total unreduced.'
        discountType:
          type: integer
          description: |
            Tipul discountului. `1` = valoric, cu valoarea in `discountValue`. `2` = procentual, cu procentul in `discountPercentage`. Implicit `2`: o linie de discount fara `discountType`, dar cu ambele valori trimise, aplica procentul.

            **Trimite doar `1` sau `2`.** O alta valoare nu e respinsa, dar produce un document gresit: discountul valoric se scade din total fara sa ajusteze TVA-ul, iar un discount procentual e ignorat complet. Pentru un produs de 100 lei cu TVA 21% si un discount de 10 lei, `discountType: 1` da 108.9, iar o valoare in afara enumerarii da 111.
          x-description-en: |
            Discount type. `1` = value discount, with the amount in `discountValue`. `2` = percentage discount, with the percentage in `discountPercentage`. Defaults to `2`: a discount line without `discountType`, but with both values sent, applies the percentage.

            **Send only `1` or `2`.** Any other value is not rejected, but it produces an incorrect document: a value discount is subtracted from the total without adjusting VAT, and a percentage discount is ignored entirely. For a 100 RON product with 21% VAT and a 10 RON discount, `discountType: 1` gives 108.9, while a value outside the enumeration gives 111.
          default: 2
          enum:
          - 1
          - 2
        discountValue:
          type: number
          exclusiveMaximum: 0
          description: 'Valoarea discountului, pentru discount valoric, cand `discountType` este `1`. **Trebuie sa fie negativa**, deci se trimite cu semnul minus: `-10` pentru un discount de 10 lei. O valoare pozitiva nu e respinsa, dar **creste** totalul in loc sa il scada - un produs de 100 lei cu `discountValue: 10` da 133.1, nu 108.9.'
          x-description-en: 'Discount value, for value discounts, when `discountType` is `1`. **It must be negative**, so send it with a minus sign: `-10` for a 10 RON discount. A positive value is not rejected, but it **increases** the total instead of reducing it - a 100 RON product with `discountValue: 10` gives 133.1, not 108.9.'
        discountPercentage:
          type: number
          exclusiveMinimum: 0
          maximum: 100
          description: Procentul discountului. Se foloseste pentru discount procentual, cand `discountType` este `2`. Valoarea trebuie sa fie mai mare decat 0 si cel mult 100.
          x-description-en: Discount percentage. Used for percentage discounts, when `discountType` is `2`. The value must be greater than 0 and at most 100.
        translatedName:
          type: string
          description: Numele produsului in limba documentului
          x-description-en: Product name in document language
        translatedMeasuringUnit:
          type: string
          description: Unitatea de masura in limba documentului
          x-description-en: Unit name in document language
        saveToDb:
          type: boolean
          description: 'Salveaza produsul in nomenclator daca e nou. Cand produsul exista deja si e trimis cu `saveToDb: true`, datele lui din nomenclator se actualizeaza din cerere - inclusiv numele. La descarcare de gestiune (`useStock: true`) actualizarea se face oricum, chiar si cu `saveToDb: false`.'
          x-description-en: 'Saves the product to the catalogue if it is new. When the product already exists and is sent with `saveToDb: true`, its catalogue record is updated from the request - including the name. With stock discharge (`useStock: true`) the update happens regardless, even with `saveToDb: false`.'
          default: false
        useSBProductName:
          type: boolean
          description: |
            Controleaza ce nume apare pe factura cand produsul este identificat prin `code`, iar denumirea trimisa in `name` difera de cea din nomenclator. `true` = pe factura se foloseste numele produsului din SmartBill, iar numele din nomenclator NU se modifica. `false` sau absent = pe factura se foloseste numele trimis prin `name`, iar acesta suprascrie numele produsului in nomenclator (inclusiv cand `saveToDb` este `false`). Necesita setarea "Foloseste cod produs" activata pe firma.
          x-description-en: |
            Controls which name appears on the invoice when the product is matched by `code` and the name sent in `name` differs from the one in the nomenclature. `true` = the invoice uses the product name from SmartBill and the nomenclature name is NOT changed. `false` or omitted = the invoice uses the name sent in `name`, which overwrites the product name in the nomenclature (even when `saveToDb` is `false`). Requires the "Foloseste cod produs" setting enabled for the company.
          default: false
    InvoicePayment:
      type: object
      description: Plata la crearea facturii
      x-description-en: Payment at invoice creation
      properties:
        value:
          type: number
          description: Suma platii
          x-description-en: Payment amount
        paymentSeries:
          type: string
          description: Seria chitantei
          x-description-en: Receipt series
        type:
          type: string
          description: Tipul platii
          x-description-en: Payment type
          enum:
          - Chitanta
          - Bon
          - Card
          - Card online
          - CEC
          - Bilet ordin
          - Ordin plata
          - Mandat postal
          - Extras de cont
          - Ramburs
          - Alta incasare
        isCash:
          type: boolean
          description: Marcheaza incasarea ca numerar. Pentru factura cu incasare, API-ul poate accepta obiectul `payment` si fara acest camp.
          default: true
    InvoiceResponse:
      type: object
      properties:
        errorText:
          type: string
          description: Mesaj de eroare (gol la succes)
          x-description-en: Error message (empty on success)
        message:
          type: string
        number:
          type: string
          description: Numarul facturii
          x-description-en: Invoice number
        series:
          type: string
          description: Seria facturii
          x-description-en: Invoice series
        url:
          type: string
          description: URL de plata (daca a fost generat)
          x-description-en: Payment URL (if generated)
        documentUrl:
          type: string
          description: URL de editare in SmartBill Cloud
          x-description-en: Edit URL in SmartBill Cloud
        documentId:
          type: string
          description: ID intern document
          x-description-en: Internal document ID
        documentViewUrl:
          type: string
          description: URL public de vizualizare
          x-description-en: Public view URL
    EstimateResponse:
      type: object
      properties:
        errorText:
          type: string
        number:
          type: string
        series:
          type: string
        url:
          type: string
        documentUrl:
          type: string
        documentId:
          type: string
        documentViewUrl:
          type: string
    InvoiceResponseV2:
      type: object
      properties:
        errorText:
          type: string
          description: Mesaj de eroare. Gol = succes.
        message:
          type: string
        number:
          type: string
          description: Numarul facturii nou-create
        series:
          type: string
          description: Seria facturii
        url:
          type: string
          description: 'Link de plata (populat doar daca trimiti `paymentUrl: "Generate URL"`)'
        documentUrl:
          type: string
          description: URL de editare in SmartBill Cloud (cere autentificare)
        documentId:
          type: integer
          description: 'ID intern al documentului. Util pentru operatii ulterioare (anulare, restore, storno). `-1` la eroare.'
        documentViewUrl:
          type: string
          description: URL public partajabil cu clientul (deschide PDF-ul fara autentificare; contine hash criptografic).
    EstimateResponseV2:
      type: object
      properties:
        errorText:
          type: string
          description: Mesaj de eroare. Gol = succes.
        message:
          type: string
        number:
          type: string
          description: Numarul proformei nou-create
        series:
          type: string
          description: Seria proformei
        url:
          type: string
        documentUrl:
          type: string
          description: URL de editare in SmartBill Cloud (cere autentificare)
        documentId:
          type: integer
          description: 'ID intern al documentului. `-1` la eroare.'
        documentViewUrl:
          type: string
          description: URL public partajabil cu clientul.
    SeriesResponse:
      type: object
      properties:
        errorText:
          type: string
        list:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                description: Numele seriei
                x-description-en: Series name
              nextNumber:
                type: integer
                description: Urmatorul numar care va fi emis
                x-description-en: Next number to be issued
              type:
                type: string
                description: Tipul seriei (f=factura, p=proforma, c=chitanta)
                x-description-en: Series type (f=invoice, p=proforma, c=receipt)
                enum:
                - f
                - p
                - c
    SendEmailRequest:
      type: object
      required:
      - companyVatCode
      - seriesName
      - number
      - type
      properties:
        companyVatCode:
          type: string
          description: CIF-ul companiei tale
          x-description-en: Your company's VAT code
        seriesName:
          type: string
          description: Seria documentului
          x-description-en: Document series name
        number:
          type: string
          description: Numarul documentului
          x-description-en: Document number
        type:
          type: string
          description: Tipul documentului. Nu e sensibil la litere mari.
          x-description-en: Document type. Not case-sensitive.
          enum:
          - factura
          - proforma
        to:
          type: string
          format: email
          description: Adresa de email a destinatarului. Daca lipseste sau e goala, se foloseste adresa clientului de pe document.
          x-description-en: Recipient email address. If missing or empty, the client email from the document is used.
        cc:
          type: string
          description: Destinatari CC (separati prin virgula)
          x-description-en: CC recipients (comma-separated)
        bcc:
          type: string
          description: Destinatari BCC (separati prin virgula)
          x-description-en: BCC recipients (comma-separated)
        subject:
          type: string
          description: Subiectul emailului (codificat Base64). Daca lipseste, se foloseste sablonul configurat in contul SmartBill.
          x-description-en: Email subject (Base64 encoded). If missing, the template configured in the SmartBill account is used.
        bodyText:
          type: string
          description: Corpul emailului (codificat Base64, suporta variabile de template). Daca lipseste, se foloseste sablonul configurat in contul SmartBill.
          x-description-en: Email body (Base64 encoded, supports template variables). If missing, the template configured in the SmartBill account is used.
    DocumentSendResponse:
      type: object
      description: Raspunsul endpointului `/document/send`. Forma difera de restul V1.
      x-description-en: Response of the `/document/send` endpoint. Its shape differs from the rest of V1.
      properties:
        status:
          type: object
          properties:
            code:
              type: integer
              description: '`0` la succes, `1` la eroare'
              x-description-en: '`0` on success, `1` on error'
            message:
              type: string
              description: Mesajul returnat de server
              x-description-en: Message returned by the server
    PaymentResponse:
      type: object
      properties:
        errorText:
          type: string
          description: Mesaj de eroare (gol la succes).
        id:
          type: string
          description: Numar de identificare unic al bonului emis. Se returneaza doar pentru incasari de tip `Bon` si este valoarea care se trimite ca parametru `id` la `GET /payment/text`.
        message:
          type: string
          description: Continutul bonului fiscal, codificat Base64. Se returneaza doar cand `returnFiscalPrinterText` este `true`. Dupa decodare, continutul trebuie scris intr-un fisier cu numele si extensia configurate pentru casa de marcat (implicit `bon.inp`).
        number:
          type: string
          description: Numarul documentului emis.
        series:
          type: string
          description: Seria documentului emis.
    StockResponse:
      type: object
      properties:
        errorText:
          type: string
        list:
          type: array
          items:
            type: object
            properties:
              warehouse:
                type: object
                properties:
                  warehouseName:
                    type: string
                    description: Numele gestiunii
                    x-description-en: Warehouse name
                  warehouseType:
                    type: string
                    description: Tipul gestiunii (en gros sau en detail)
                    x-description-en: Warehouse type (en gros or en detail)
                    enum:
                    - en gros
                    - en detail
              products:
                type: array
                items:
                  type: object
                  properties:
                    productName:
                      type: string
                      description: Numele produsului
                      x-description-en: Product name
                    productCode:
                      type: string
                      description: Codul produsului/SKU (daca firma foloseste coduri)
                      x-description-en: Product code/SKU (if company uses codes)
                    measuringUnit:
                      type: string
                      description: Unitate de masura
                      x-description-en: Unit of measure
                    quantity:
                      type: number
                      description: Cantitate in stoc
                      x-description-en: Stock quantity
    SuccessResponse:
      type: object
      properties:
        errorText:
          type: string
          example: ''
        message:
          type: string
    ErrorResponse:
      type: object
      properties:
        errorText:
          type: string
          description: Mesaj de eroare
          x-description-en: Error message
          example: Clientul este obligatoriu
    ProblemResponseV3:
      type: object
      description: >-
        Format standard de eroare pentru API-ul V3. Foloseste 'status', 'type',
        'instance' si un array 'errors' care poate contine mai multe erori
        intr-un singur raspuns.
      properties:
        status:
          type: integer
          description: Codul HTTP al raspunsului.
          example: 400
        type:
          type: string
          description: >-
            Categoria erorii: authentication_error, authorization_error,
            invalid_request_error, validation_error sau api_error.
          example: validation_error
        instance:
          type: string
          description: Calea request-ului care a generat eroarea.
          example: /SBORO/api/v3/companies/1234/clients
        errors:
          type: array
          description: Lista de erori (poate contine mai multe intrari).
          items:
            type: object
            properties:
              code:
                type: string
                example: invalid_field_value
              message:
                type: string
                example: The 'limit' field must be between 1 and 100.
              docUrl:
                type: string
                example: https://api.smartbill.ro/#v3-error-validation_error
              param:
                type: string
                description: Prezent cand eroarea poate fi asociata cu un camp sau parametru.
                example: limit
    SupplierV3:
      type: object
      properties:
        id:
          type: string
          description: ID unic furnizor
          example: sup_019f17cde03e7093a40f9a4b4fd30d14
        name:
          type: string
          example: Furnizor Exemplu SRL
        vatCode:
          type: string
          description: CIF furnizor
          example: RO44444444
        regCom:
          type: string
          example: J40/9999/2021
        code:
          type: string
          description: Cod intern furnizor
          example: FURN003
        address:
          type: string
          example: Str. Exemplu 10
        city:
          type: string
          example: Bucuresti
        county:
          type: string
          example: Bucuresti
        country:
          type: string
          example: Romania
        bank:
          type: string
          example: Banca Exemplu
        iban:
          type: string
          example: RO49AAAA1B31007593840000
        email:
          type: string
          format: email
          example: supplier@example.com
        contact:
          type: string
          example: Maria Ionescu
        phone:
          type: string
          example: "0722000003"
        isVatPayer:
          type: boolean
          description: Platitor TVA
          example: true
    ClientV3:
      type: object
      properties:
        id:
          type: string
          description: ID unic client
          example: cus_019f17cde09d73a69826a35d9c640d13
        name:
          type: string
          example: Client Exemplu SRL
        vatCode:
          type: string
          example: RO77777777
        regCom:
          type: string
          example: J40/3333/2020
        code:
          type: string
          example: CLI003
        address:
          type: string
          example: Str. Exemplu 1
        city:
          type: string
          example: Bucuresti
        county:
          type: string
          example: Bucuresti
        country:
          type: string
          example: Romania
        bank:
          type: string
          example: Banca Exemplu
        iban:
          type: string
          example: RO49AAAA1B31007593840000
        email:
          type: string
          format: email
          example: client@example.com
        contact:
          type: string
          example: Elena Radu
        phone:
          type: string
          example: "0722000005"
        isVatPayer:
          type: boolean
          example: false
        brand:
          type: string
          description: Brand asociat
          example: ""
        deliveryAddresses:
          type: array
          description: Adrese de livrare
          items:
            $ref: '#/components/schemas/DeliveryAddressV3'
    DeliveryAddressV3:
      type: object
      properties:
        description:
          type: string
          example: Auto-generated address 1
        address:
          type: string
          example: Str. Livezilor 3
        addressAdditionalInfo:
          type: string
          example: ""
        addressLine3:
          type: string
          example: ""
        city:
          type: string
          example: Bucuresti
        county:
          type: string
          example: Bucuresti
        country:
          type: string
          example: Romania
        zipCode:
          type: string
          example: ""
        defaultAddress:
          type: boolean
          description: Adresa implicita de livrare
          example: true
    WarehouseV3:
      type: object
      properties:
        id:
          type: string
          description: ID unic gestiune
          example: ware_019f17cddf1272f2a7405cb6c7f30d15
        name:
          type: string
          example: Depozit Exemplu
        description:
          type: string
          example: Gestiune de exemplu
        type:
          type: string
          description: Tipul gestiunii
          enum:
            - en gros
            - en detail
          example: en gros
        keeper:
          type: string
          description: Gestionar
          example: Popescu Ion
        address:
          type: string
          example: Str. Depozitelor 10
        city:
          type: string
          example: Berlin
        county:
          type: string
          example: Bucuresti
        country:
          type: string
          description: Codul tarii (ISO 3166-1 alpha-2)
          example: DE
        isCustody:
          type: boolean
          description: Gestiune in custodie
          example: false
    ProductV3:
      type: object
      properties:
        id:
          type: string
          description: ID unic produs
          example: prod_019f17cde0fd7625abd43bf960d10d16
        name:
          type: string
          example: Apa sticla 0.5 - AM001
        description:
          type: string
          example: Descriere apa sticla 0.5
        code:
          type: string
          description: Cod produs (SKU)
          example: ""
        isService:
          type: boolean
          description: Este serviciu
          example: false
        price:
          type: number
          description: Pretul unitar
          example: 2.0
        measuringUnitName:
          type: string
          description: Unitatea de masura
          example: sticla
        currency:
          type: string
          description: Moneda pretului
          example: RON
        vatPercentage:
          type: number
          description: Cota TVA
          example: 21.0
        vatName:
          type: string
          description: Denumirea cotei TVA
          example: Normala
        isVatIncluded:
          type: boolean
          description: Pretul include TVA
          example: true
        cnCode:
          type: string
          description: Cod CN (Combined Nomenclature) din nomenclator, fara descriere. Se returneaza ca text - zerourile din fata sunt semnificative. Gol daca nu e setat.
          example: "01022110"
        cpvCode:
          type: string
          description: Cod CPV din nomenclator, fara descriere, fara cifra de control. Gol daca nu e setat.
          example: "15981100"
        countryOfOrigin:
          type: string
          description: Tara de origine
          example: ""
        containerDeposits:
          type: array
          description: Garantii SGR
          items:
            type: object
            properties:
              type:
                type: string
                description: Tipul garantiei SGR
                example: Garantie SGR Plastic
              quantity:
                type: integer
                example: 1
  responses:
    Unauthorized:
      description: Autentificare esuata
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedResponse'
          examples:
            credentiale_invalide:
              summary: Credentiale invalide (user/parola gresite)
              value:
                key: "!.oresp@&"
                successfully: false
                errorText: Autentificare esuata. Va rugam verificati datele si incercati din nou.
                errorCode: "0"
                message: ''
                operationExecuted: false
                cooldown: 0
                needsConsent: false
            cif_firma_invalid:
              summary: CIF firma invalid
              value:
                key: "!.oresp@&"
                successfully: false
                errorText: Firma la care incercati sa va conectati nu mai este disponibila in Cloud.
                errorCode: "0"
                message: ''
                operationExecuted: false
                cooldown: 0
                needsConsent: false
    ServerError:
      description: Eroare interna de server. Poate aparea cand numele campurilor sunt trimise cu casing gresit (ex. `Price` in loc de `price`). Raspunsul este `text/html`, nu JSON - nu poate fi parsat programatic.
      content:
        text/html:
          schema:
            type: string
          example: |
            <!DOCTYPE html><html><head><title>Error report</title></head>
            <body><h1>HTTP Status 500 - Internal Server Error</h1></body></html>
    UnauthorizedV3:
      description: Autentificare esuata
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemResponseV3'
          example:
            status: 401
            type: authentication_error
            instance: /SBORO/api/v3/companies/1234/clients
            errors:
              - code: invalid_api_key
                message: Invalid API key provided.
                docUrl: https://api.smartbill.ro/#v3-error-authentication_error
    ForbiddenV3:
      description: Permisiuni insuficiente
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemResponseV3'
          example:
            status: 403
            type: authorization_error
            instance: /SBORO/api/v3/companies/1234/clients
            errors:
              - code: insufficient_permissions
                message: You do not have the permission to perform this action
                docUrl: https://api.smartbill.ro/#v3-error-authorization_error
    MethodNotAllowedV3:
      description: Metoda HTTP nepermisa
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemResponseV3'
          example:
            status: 405
            type: invalid_request_error
            instance: /SBORO/api/v3/companies/1234/clients
            errors:
              - code: method_not_allowed
                message: The HTTP method is not allowed for the requested resource.
                docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
    NotAcceptableV3:
      description: Format neacceptat (Accept header invalid)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemResponseV3'
          example:
            status: 406
            type: invalid_request_error
            instance: /SBORO/api/v3/companies/1234/clients
            errors:
              - code: invalid_accept_header
                message: The requested resource is not available in the requested format.
                docUrl: https://api.smartbill.ro/#v3-error-invalid_request_error
