+40 723 640 317 [email protected]
WeBill
Dezvoltatori

WeBill API v6

API-ul v6 WeBill permite unei aplicații externe (magazin online, ERP, CRM, aplicație de pontaj) să emită și să gestioneze facturi fiscale, proforme, încasări, stornări, clienți și pontaje în contul unei companii WeBill și să citească datele companiei.

Adresă de bază
https://webill.ro
Format
JSON
Autentificare
Bearer
Cereri documentate
46

Prima cerere: Obținere token

curl -X POST 'https://webill.ro/api/v6/auth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": "API_USER",
  "client_secret": "API_SECRET",
  "company_id": "1"
}'

Pornire rapidă

  1. În WeBill, la Setări companie > API: copiază Client ID (login-ul contului care deține compania) și ID companie, apoi generează Secretul API (se afișează o singură dată; fiecare companie are secretul ei).
  2. În Postman, importă colecția și fișierul de mediu webident-crm-api-v6.postman_environment.json (sau creează un Environment cu variabilele de mai jos) și completează base_url, api_user, api_secret și, dacă ai mai multe companii, company_id.
  3. Rulează Autentificare > Obținere token: tokenul se salvează automat în api_token și este folosit de toate celelalte cereri (autentificarea Bearer e setată la nivel de colecție).
  4. Rulează Nomenclatoare > Facturi: completează automat serie_id, receipt_serie_id, delegate_id și bank_id cu valorile marcate „Implicit” în Setări, altfel primele active.
  5. Cererile din fiecare folder pot fi rulate de sus în jos (Collection Runner): fiecare cerere care creează ceva salvează ID-ul în Environment pentru cererile următoare.

⚠️ Cererile emit documente fiscale reale în compania tokenului (numere consumate din serie). Testează pe o companie / serie de test.

Autentificare

  • POST /api/v6/auth/token cu login-ul utilizatorului și secretul API al companiei → access_token.
  • Toate celelalte cereri trimit Authorization: Bearer {access_token} (alternativ headerul X-API-Token: {access_token}). Tokenul în query string nu este acceptat.
  • Tokenul este valabil 12 ore (expires_in: 43200); nu există refresh — la 401 cere un token nou și reia cererea.
  • Un utilizator are un singur token activ pe companie: un token nou îl invalidează imediat pe cel vechi. Dacă două integrări folosesc același utilizator și aceeași companie, ele se deconectează reciproc; folosește câte un utilizator pentru fiecare integrare sau partajează tokenul.
  • Toate datele sunt limitate la compania tokenului: ID-urile altor companii răspund 404.
Răspuns 401 Cauză
(401.0) Acces refuzat: lipseste tokenul de acces Lipsește tokenul.
(401.1) Acces refuzat: token de acces invalid Token necunoscut sau înlocuit de un token mai nou.
(401.2) Tokenul de acces a expirat Tokenul a expirat (după 12 ore). Cererile următoare cu același token primesc 401.1.
(401.3) Compania tokenului nu mai exista Compania tokenului nu mai există.
(401.4) Acces refuzat: compania este inchisa Compania a fost închisă; nu se mai emit tokenuri, iar cele emise sunt refuzate.

Format cereri

  • Trimite JSON cu Content-Type: application/json și Accept: application/json. Sunt acceptate și cererile form-data; un corp JSON trimis cu alt Content-Type este decodat oricum.
  • Date: AAAA-LL-ZZ. Sume: numere (121.5); se acceptă și virgula zecimală în string ("121,5"). Boolean: true / false (se acceptă și 1, "da", "yes", "on").
  • Multe câmpuri au și denumiri alternative (camelCase, ex. clientId, serieId); în documentație apar denumirile principale, recomandate.
  • În Postman, o cerere care folosește o variabilă încă goală (ex. product_id când compania nu are produse, project_id fără proiecte) este sărită, cu motivul în Console. Restul colecției rulează mai departe.
  • O rută sau o metodă inexistentă sub /api/v6/ răspunde tot în formatul de mai jos: 404 Ruta nu exista, 405 Metoda nu este permisa pe aceasta ruta.
  • Toate mesajele (statusMessage și textele din errors) sunt în limba română, fără diacritice. În mesajele de validare numele câmpului apare cu spații în loc de _ (ex. Campul serie id este obligatoriu.); cheile din errors rămân numele câmpurilor. Codul HTTP și errors.code sunt cele de urmărit în integrare, nu textul.

Format răspunsuri

Succes (codul HTTP este egal cu status):

{ "status": 200, "statusMessage": "Document creat", "data": { ... } }

Eroare:

{ "status": 422, "statusMessage": "Cota TVA selectata nu este disponibila.", "errors": { "code": "INVALID_TAX" }, "data": null }
  • statusMessage este textul de afișat / logat; data este null la erori.
  • errors este [] sau un obiect: erori pe câmpuri ({"items": ["..."]}) sau {"code": "..."} pentru refuzurile de business pe documente și încasări. Integrează-te pe status + errors.code, nu pe textul mesajului.
  • Descărcările (/download) răspund direct cu fișierul PDF (Content-Type: application/pdf, Content-Disposition: attachment; filename=...); erorile lor sunt JSON.
HTTP Când
200 / 201 Succes (201 doar la un pontaj nou).
400 JSON invalid, parametri lipsă la nomenclatoare, alte erori neașteptate ale operației.
401 Autentificare (vezi mai sus).
403 Resursa există, dar nu aparține companiei (proiecte).
404 Resursa nu există în compania tokenului.
409 Starea documentului nu permite operația (factură trimisă în SPV, cu încasări, deja stornată etc.).
422 Date invalide (validare).
429 Limita de cereri depășită. Corpul nu are formatul de mai sus; respectă headerul Retry-After.

Coduri errors.code

Cod HTTP Semnificație
INVALID_CLIENT 422 Clientul nu este disponibil.
INVALID_INVOICE_SERIE / INVALID_PROFORMA_SERIE 422 Seria nu există, nu e activă sau nu e a companiei.
INVALID_RECEIPT_SERIE 422 Seria de chitanțe nu este disponibilă.
INVALID_DELEGATE 422 Delegatul nu este disponibil.
INVALID_BANK_ACCOUNT 422 Contul bancar nu este disponibil.
INVALID_TAX 422 Cota TVA nu este disponibilă.
INVALID_TAX_CLIENT 422 Cota TVA aleasă (ex. taxare inversă) nu se aplică acestui client.
INVALID_PRODUCT 422 Produsul nu există în nomenclatorul companiei.
INVALID_ITEMS 422 Documentul nu are nicio linie validă.
INVOICE_PAYMENT_AMOUNT_INVALID 422 Suma încasării trebuie să fie mai mare decât zero.
INVOICE_PAYMENT_TYPE_INVALID 422 Tipul de încasare nu este disponibil.
INVOICE_PAYMENT_NOT_ALLOWED 409 Documentul nu mai acceptă încasări (anulat, stornat, proformă convertită etc.).
INVOICE_CANCEL_HAS_PAYMENTS 409 Factura are încasări și nu poate fi anulată (șterge încasările sau storneaz-o).
INVOICE_CANCEL_NOT_ALLOWED 409 Factura nu poate fi anulată în starea curentă.
INVOICE_STORNO_HAS_PAYMENTS 409 Factura are încasări: trimite payments_action (credit sau refund).
INVOICE_STORNO_PAYMENTS_ACTION_INVALID 422 payments_action invalid.
INVOICE_STORNO_NOT_ALLOWED 409 Factura nu poate fi stornată în starea curentă.
AMBIGUOUS_DOCUMENT 409 Caută după serie și număr: mai multe documente se potrivesc; errors.candidates[].
CLIENT_MISMATCH 404 Caută după serie și număr: documentul există, dar clientul nu corespunde.
COMPANY_MISMATCH 404 Caută după serie și număr: documentul există, dar emitentul are alt cod fiscal.
DATE_MISMATCH 404 Caută după serie și număr: documentul există, dar are altă dată decât date.
DOCUMENT_NOT_FOUND 404 Caută după serie și număr: niciun document cu seria și numărul acestea.

Limite

  • 120 de cereri pe minut pentru toate rutele /api/v6 (inclusiv obținerea tokenului). Peste limită: 429 cu headerele Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining.
  • GET /clients este paginat (max. 100 pe pagină); celelalte liste nu sunt paginate.

Cache (ETag)

GET /company și toate GET /nomenclature/* răspund cu ETag și Cache-Control: no-cache, private. Păstrează răspunsul împreună cu ETag-ul și la cererea următoare trimite headerul If-None-Match: <ETag>: dacă datele nu s-au schimbat primești 304 Not Modified, fără corp, și folosești copia ta; altfel 200 cu datele noi și un ETag nou. ETag-ul se schimbă la orice modificare a datelor (o serie, un cont, un produs nou). Cererea 304 se numără în limita de 120 pe minut, dar nu mai transferă datele.

  • Recomandare: citește Nomenclatoare > Facturi o dată la pornirea integrării (sau înaintea unei serii de facturi) și revalidează-l, în loc să-l ceri înaintea fiecărei facturi.
  • Răspunsurile sunt private (depind de token): un proxy partajat nu le păstrează.

Ciclul unei facturi

  1. Emitere — POST /invoices creează direct o factură emisă, numerotată în serie (API-ul nu creează ciorne). Transmiterea în SPV (e-Factura) se face din WeBill, după setările companiei.
  2. Modificare — PATCH /invoices/{id} cât timp factura nu a fost trimisă în SPV.
  3. Încasare — POST /invoices/{id}/receipts (sau direct la emitere cu POST /invoices/with-receipt); o plată pentru mai multe facturi: POST /invoices/receipts/bulk.
  4. Corectare — înainte de SPV și fără încasări: POST /invoices/{id}/cancel (anulare). După SPV: stornare totală sau parțială, POST /invoices/{id}/storno.
Stare Modificare Încasări Anulare Stornare
emisa, netrimisă în SPV da da da, fără încasări da
emisa, trimisă în SPV nu (409) da devine stornare da
anulata nu nu idempotent nu
storno (factura inversă) — doar restituiri (sume negative) dacă nu e trimisă în SPV nu

Scenarii frecvente

  • Factura după numărul tipărit: GET /invoices/find?serie=WB&number=12&company_vat=... (opțional și date, client_vat, client_name) întoarce factura ca GET /invoices/{id} doar dacă seria, numărul, codul fiscal al emitentului și fiecare parametru opțional trimis corespund exact; altfel o eroare cu errors.code, niciodată un document apropiat. La fel GET /proforme/find.
  • Datele emitentului: GET /company — identitatea fiscală, adresa, conturile bancare, punctele de lucru, modulele pornite și dacă e-Factura e conectată.
  • Comandă plătită online (magazin): POST /invoices/with-receipt cu clientul inline, order_id = ID-ul comenzii și receipt.type = card. Factura și încasarea se creează în aceeași tranzacție; reîncercarea cu același order_id în 2 minute nu dublează factura. Apoi POST /invoices/{id}/email.
  • Comandă cu plata ulterior (OP / ramburs): POST /invoices, iar la confirmarea plății POST /invoices/{id}/receipts cu type = op sau ramburs.
  • Extras bancar cu o plată pentru mai multe facturi: citește restul de plată (GET /invoices/{id} → totals.stats.rest) și trimite POST /invoices/receipts/bulk cu expected_balances.
  • Retur parțial: GET /invoices/{id}/storno (liniile și ce a rămas de stornat), apoi POST /invoices/{id}/storno cu lines.
  • Ofertă / avans: POST /proforme, încasare pe proformă; proforma se convertește în factură din WeBill.

Variabile de mediu

Variabilă Setată de Descriere
base_url tine https://webill.ro
api_user tine Login-ul utilizatorului WeBill.
api_secret tine Secretul API al companiei.
company_id tine ID-ul companiei; obligatoriu doar dacă utilizatorul are mai multe companii cu același secret.
api_token Obținere token Tokenul Bearer.
serie_id, receipt_serie_id, delegate_id, bank_id Nomenclatoare > Facturi Seria de facturi, delegatul și contul RON implicite (altfel primele), prima serie cu chitanțier.
proforma_serie_id Nomenclatoare > Facturi Seria de proforme implicită (altfel prima).
tax_id Nomenclatoare > Facturi Cota TVA implicită.
product_id Nomenclatoare > Produse Primul produs din nomenclator.
country_code, currency tine Ex. RO, EUR.
client_id, client_vat Clienți > Creează persoană juridică Clientul folosit în exemplele de documente.
project_id Proiecte > Listă Primul proiect.
invoice_id, invoice_id_2, invoice_id_3, paid_invoice_id Facturi fiscale > Creează ... Facturile create de exemple.
company_vat Companie > Detalii companie Codul fiscal al companiei, pentru Caută după serie și număr.
invoice_serie, invoice_number Facturi fiscale > Creează Seria și numărul facturii, pentru Caută după serie și număr.
receipt_id, cash_receipt_id Încasări - Creează ... Încasările create de exemple.
storno_line_id Variante de stornare Prima linie care se poate storna.
proforma_id, proforma_receipt_id Proforme > Creează ... Proforma și încasarea ei.
proforma_serie, proforma_number Proforme > Creează Seria și numărul proformei.
today automat Data de azi (AAAA-LL-ZZ), calculată la fiecare cerere dacă nu e setată în Environment.

Autentificare

Obținerea tokenului Bearer. Nu cere autentificare.

Obținere token

POST /api/v6/auth/token fără token

Emite tokenul de acces pentru o companie. Tokenul se salvează automat în variabila api_token.

Body

Câmp Tip Obligatoriu Detalii
client_id string da Client ID din Setări companie > API: login-ul contului care deține compania (alias: login).
client_secret string da Secretul API al companiei, din Setări companie > API (alias: secret).
company_id int nu Compania pentru care se emite tokenul. Obligatoriu când același utilizator are mai multe companii cu același secret.

Alternativ, credențialele se pot trimite în header Authorization: Basic base64(login:secret); company_id rămâne în body.

Răspuns: token_type (Bearer), access_token, expires_in (secunde; mereu 43200 = 12 ore), issued_at (ora serverului, Europe/Bucharest), company (id, vat), owner (id, login).

Un token nou pentru același utilizator și aceeași companie îl invalidează imediat pe cel anterior. Cere un token nou la expirare (401.2) sau la 401.1, nu la fiecare cerere.

Erori

  • 401 (401) Date de autentificare invalide — lipsește login-ul sau secretul.
  • 401 (401) Utilizator inexistent.
  • 401 (401) Secret sau companie invalida — secretul nu se potrivește cu nicio companie a utilizatorului (sau cu company_id).
  • 422 (422) Selectati compania (company_id) cand exista mai mult de o companie activa (errors.company_id).
curl -X POST 'https://webill.ro/api/v6/auth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": "API_USER",
  "client_secret": "API_SECRET",
  "company_id": "1"
}'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "token_type": "Bearer",
    "access_token": "a3f1c9...(128 de caractere hex)",
    "expires_in": 43200,
    "scope": null,
    "issued_at": "2026-10-29 12:53:47",
    "company": {
      "id": 1,
      "vat": "RO10000008"
    },
    "owner": {
      "id": 1,
      "login": "api.demo"
    }
  }
}

Nomenclatoare

Listele de valori ale companiei: serii, delegați, conturi bancare, cote TVA, țări, județe, curs valutar și produse. ID-urile de aici sunt cele pe care le primesc documentele. Nomenclatoarele se schimbă rar: păstrează-le în cache și revalidează-le cu If-None-Match (304 fără corp când nu s-a schimbat nimic). Nomenclatoare > Facturi aduce într-o singură cerere tot ce trebuie pentru o factură.

Facturi

GET /api/v6/nomenclature/invoice

Tot ce trebuie pentru a construi o factură sau o proformă. Doar elementele active ale companiei, în ordinea din WeBill (Setări, săgețile sus / jos). Un document creat fără serie_id, delegate_id sau bank_accounts ia ce e marcat „Implicit” în Setări (is_default: true: seria, delegatul, contul monedei documentului), altfel prima serie, primul delegat, toate conturile active.

Cheie Conținut
currencies[] code, name — monedele acceptate în currency.
languages[] code (ro, en), name.
invoice_series[] id, serie, current_number (următorul număr), receipt_serie / receipt_current_number (chitanțierul seriei, folosit la încasările cash), currency, is_default, is_active. rec_serie / rec_current_index sunt aliasuri vechi.
proforma_series[] id, serie, current_number, is_default, is_active.
delegates[] id, name, transport_type, transport_number, is_default, is_active.
banks[] id, bank, iban, currency, label, is_default (cel mult unul pe monedă), is_active — pentru bank_accounts.
taxes[] id, name, percent, categorie (categoria e-Factura: S, Z, E, AE, K, O ...), is_default, is_active — pentru tax_id / tax_value.
units[] id, code (codul UN/ECE, ex. H87, HUR), name (denumirea dată de companie, altfel cea standard), default_name, is_default — unitățile de măsură ale companiei (Setări > Unități de măsură), în ordinea din editorul de documente. Pe o linie, um primește code sau name.
curl 'https://webill.ro/api/v6/nomenclature/invoice' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Nomenclatoare facturi",
  "data": {
    "currencies": [
      {
        "code": "RON",
        "name": "RON - Leu romanesc"
      },
      {
        "code": "EUR",
        "name": "EUR - Euro"
      },
      {
        "code": "USD",
        "name": "USD - Dolarul american"
      },
      {
        "code": "MDL",
        "name": "MDL - Leul moldovenesc"
      },
      {
        "code": "GBP",
        "name": "GBP - Lira sterlina"
      },
      {
        "code": "CHF",
        "name": "CHF - Francul elvetian"
      },
      {
        "code": "AUD",
        "name": "AUD - Dolarul australian"
      },
      {
        "code": "BGN",
        "name": "BGN - Leva bulgareasca"
      },
      {
        "code": "CAD",
        "name": "CAD - Dolarul canadian"
      },
      {
        "code": "CZK",
        "name": "CZK - Coroana ceha"
      },
      {
        "code": "DKK",
        "name": "DKK - Coroana daneza"
      },
      {
        "code": "HUF",
        "name": "HUF - 100 Forinti maghiari"
      },
      {
        "code": "EGP",
        "name": "EGP - Lira egipteana"
      },
      {
        "code": "JPY",
        "name": "JPY - 100 Yeni japonezi"
      },
      {
        "code": "NOK",
        "name": "NOK - Coroana norvegiana"
      },
      {
        "code": "PLN",
        "name": "PLN - Zlotul polonez"
      },
      {
        "code": "RUB",
        "name": "RUB - Rubla ruseasca"
      },
      {
        "code": "SEK",
        "name": "SEK - Coroana suedeza"
      },
      {
        "code": "TRY",
        "name": "TRY - Lira turceasca"
      },
      {
        "code": "ZAR",
        "name": "ZAR - Randul sud-african"
      },
      {
        "code": "BRL",
        "name": "BRL - Realul brazilian"
      },
      {
        "code": "CNY",
        "name": "CNY - Renminbi-ul chinezesc"
      },
      {
        "code": "INR",
        "name": "INR - Rupia indiana"
      },
      {
        "code": "KRW",
        "name": "KRW - 100 Woni sud-coreeni"
      },
      {
        "code": "MXN",
        "name": "MXN - Peso-ul mexican"
      },
      {
        "code": "NZD",
        "name": "NZD - Dolarul neo-zeelandez"
      },
      {
        "code": "RSD",
        "name": "RSD - Dinarul sarbesc"
      },
      {
        "code": "UAH",
        "name": "UAH - Hryvna ucraineana"
      },
      {
        "code": "AED",
        "name": "AED - Dirhamul Emiratelor Arabe"
      },
      {
        "code": "THB",
        "name": "THB - Bahtul thailandez"
      },
      {
        "code": "XAU",
        "name": "XAU - Gramul de aur"
      },
      {
        "code": "XDR",
        "name": "XDR - DST"
      }
    ],
    "languages": [
      {
        "code": "ro",
        "name": "RO - Română"
      },
      {
        "code": "en",
        "name": "EN - English"
      }
    ],
    "invoice_series": [
      {
        "id": 1,
        "serie": "WB",
        "current_number": 1,
        "receipt_serie": "CH",
        "receipt_current_number": 1,
        "rec_serie": "CH",
        "rec_current_index": 1,
        "currency": "RON",
        "is_default": false,
        "is_active": true
      }
    ],
    "proforma_series": [
      {
        "id": 1,
        "serie": "PF",
        "current_number": 1,
        "is_default": false,
        "is_active": true
      }
    ],
    "delegates": [
      {
        "id": 1,
        "name": "Email",
        "transport_type": null,
        "transport_number": null,
        "is_default": false,
        "is_active": true
      },
      {
        "id": 2,
        "name": "Ion Delegat",
        "transport_type": null,
        "transport_number": null,
        "is_default": false,
        "is_active": true
      }
    ],
    "banks": [
      {
        "id": 1,
        "bank": "ING",
        "iban": "RO49INGB0000999900000000",
        "currency": "RON",
        "label": "ING - RO49INGB0000999900000000 (RON)",
        "is_default": false,
        "is_active": true
      }
    ],
    "taxes": [
      {
        "id": 9,
        "name": "TVA 21%",
        "percent": 21,
        "categorie": "S",
        "is_default": true,
        "is_active": true
      },
      {
        "id": 10,
        "name": "Fara TVA",
        "percent": 0,
        "categorie": "O",
        "is_default": false,
        "is_active": true
      }
    ],
    "units": [
      {
        "id": 893,
        "code": "H87",
        "name": "BUC",
        "default_name": "H87 - bucata",
        "is_default": false
      }
    ]
  }
}

Clienți

GET /api/v6/nomenclature/client

Tipurile de client (client_types: pf persoană fizică, pj persoană juridică — la clienți se trimit ca is_pf: true/false) și țările active (countries[]: code, name), cu cele fixate primele.

curl 'https://webill.ro/api/v6/nomenclature/client' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Nomenclatoare clienti",
  "data": {
    "client_types": [
      {
        "code": "pf",
        "name": "Persoană fizică"
      },
      {
        "code": "pj",
        "name": "Persoană juridică"
      }
    ],
    "countries": [
      {
        "code": "RO",
        "name": "Romania"
      }
    ]
  }
}

Județe după țară

GET /api/v6/nomenclature/states

Județele / regiunile unei țări: country (code, name) și states[] (code, name), ordonate după nume. Codul (B, CJ, IF ...) se trimite în câmpul state al clientului.

Query: country (obligatoriu) — codul țării (RO), sau o parte din numele ei.

Erori: 400 Parametrul country este obligatoriu; 404 Tara nu a fost gasita.

curl 'https://webill.ro/api/v6/nomenclature/states?country=RO' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Nomenclatoare regiuni",
  "data": {
    "country": {
      "code": "RO",
      "name": "Romania"
    },
    "states": [
      {
        "code": "AB",
        "name": "Alba"
      },
      {
        "code": "B",
        "name": "Bucuresti"
      },
      {
        "code": "IF",
        "name": "Ilfov"
      }
    ]
  }
}

Curs valutar

GET /api/v6/nomenclature/exchange-rate

Cursul BNR pe care WeBill îl folosește pentru un document cu data cerută: ultimul curs publicat înaintea datei (cursul zilei bancare anterioare).

Query

  • currency (obligatoriu): codul monedei, 3 litere (EUR, USD ...). Pentru RON se întoarce cursul EUR.
  • date (opțional): AAAA-LL-ZZ; implicit azi. Alternativ year, month, day.

Răspuns: requested_currency, currency, rate, multiplier (1 pentru majoritatea monedelor; 100 pentru HUF / JPY: cursul este pentru 100 de unități), requested_date, rate_date, source (BNR).

Erori: 400 Parametrul currency este obligatoriu. / ... trebuie sa aiba 3 caractere. / Parametrul date trebuie sa fie in format YYYY-MM-DD.; 404 Cursul valutar nu a fost gasit pentru moneda solicitata.

curl 'https://webill.ro/api/v6/nomenclature/exchange-rate?currency=EUR&date=2026-11-13' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Curs valutar",
  "data": {
    "requested_currency": "EUR",
    "currency": "EUR",
    "rate": 5,
    "multiplier": 1,
    "requested_date": "2026-10-29",
    "rate_date": "2026-09-29",
    "source": "BNR"
  }
}

Produse și servicii

GET /api/v6/nomenclature/products

Produsele și serviciile active din nomenclatorul companiei (Facturi > Produse și servicii), ordonate după nume. Nu este paginat.

Query: q (opțional) — caută în denumire sau după codul exact.

products[]: id, name, details, code, unit, unit_price, currency, tax_id, tax_included, cpv_code, tracks_stock, tracks_lots, stock.

Cu modulul Gestiune pornit, stock are câte un rând pe gestiune activă care a avut articolul: warehouse_id, warehouse_name, quantity, reserved, lots[] (lot, expiry_date, quantity). Fără urmărire de stoc (sau cu modulul oprit), tracks_stock / tracks_lots sunt false și stock este null.

Pe o linie de factură / proformă poți trimite doar product_id și qty: restul câmpurilor se completează din produs (le poți suprascrie trimițându-le).

curl 'https://webill.ro/api/v6/nomenclature/products' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Nomenclator produse",
  "data": {
    "products": [
      {
        "id": 1,
        "name": "Abonament lunar",
        "details": null,
        "code": "ABN-01",
        "unit": "H87",
        "unit_price": 121,
        "currency": "RON",
        "tax_id": 9,
        "tax_included": true,
        "cpv_code": null,
        "tracks_stock": false,
        "tracks_lots": false,
        "stock": null
      }
    ]
  }
}

Companie

Datele companiei tokenului (emitentul documentelor), doar de citit. Utile pentru afișarea emitentului, verificarea plătitorului de TVA sau a modulelor pornite înainte de a emite.

Detalii companie

GET /api/v6/company

Datele companiei tokenului, doar de citit: identitatea fiscală și adresa așa cum apar pe documente, punctele de lucru, modulele pornite, starea la ANAF, conectarea e-Factura (SPV) și preferințele documentelor. Tot ce trebuie pentru o factură (serii, conturi bancare, cote TVA, delegați, unități de măsură) este într-o singură cerere, Nomenclatoare > Facturi.

Răspunde cu ETag: retrimite-l în If-None-Match și primești 304 fără corp cât timp datele nu s-au schimbat (vezi Cache în descrierea colecției).

company

Câmp Detalii
id, name, alias, code ID-ul (același cu company_id de la token), denumirea legală, numele scurt și codul intern din Setări.
vat, vat_label Codul fiscal fără / cu prefixul RO (prefixul doar la plătitorii de TVA).
has_vat, vat_on_collection Plătitor de TVA; TVA la încasare (doar împreună cu has_vat).
vat_vies, reg, capital_social, bt_29 Codul VIES, nr. de înregistrare la Registrul Comerțului, capitalul social, identificatorul vânzătorului din e-Factura (BT-29). null când nu sunt completate.
administrator, email, phone Datele de contact din Setări companie.
country, state { code, name } (codurile din Nomenclatoare > Clienți / Județe) sau null.
city, address_1, address_2, zip Adresa sediului; zip este null când lipsește.
other_info[] label, value — informațiile suplimentare tipărite pe documente (ex. cont Trezorerie).
conta_cont_analitic_client Contul analitic al companiei folosit la exportul contabil.
logo_url URL-ul public al logo-ului sau null.
is_branch, cui_branch, parent_company Punct de lucru: CUI-ul punctului și compania-mamă (id, name, vat). Un punct de lucru are identitatea fiscală a companiei-mamă (vat, reg, has_vat etc.).
subscription_until Ultima zi plătită a abonamentului WeBill (AAAA-LL-ZZ) sau null.
created_at Data creării companiei în WeBill.

Celelalte chei

Cheie Conținut
anaf state (active, inactive, suspended, deregistered), state_text, state_date, synced_at — ultima verificare a companiei la ANAF; null dacă nu a fost verificată.
efactura connected (există un token SPV valabil), expires_at, autoupload (facturile se trimit automat în SPV), autodownload.
branches[] id, name, code, cui_branch, city — punctele de lucru active ale companiei (gol pentru un punct de lucru). Fiecare are propriul company_id și propriul token.
modules[] code, name — modulele opționale pornite: stock (Gestiune), offers, contracts, projects, subscriptions, accounting_export.
preferences invoice_due_date (zilele de scadență implicite), invoice_notes (observațiile implicite), invoice_payments_on_documents, autosend_invoice_to_client, export_documents, spv_alerts, spv_downloads_email, spv_max_days_send.

Secretul API, proprietarul contului și datele interne WeBill nu sunt întoarse.

curl 'https://webill.ro/api/v6/company' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Detalii companie",
  "data": {
    "company": {
      "id": 1,
      "name": "FIRMA DEMO SRL",
      "alias": null,
      "code": null,
      "vat": "10000008",
      "vat_label": "RO10000008",
      "has_vat": true,
      "vat_on_collection": false,
      "vat_vies": null,
      "reg": "J40/3066/2020",
      "capital_social": null,
      "bt_29": null,
      "administrator": null,
      "email": null,
      "phone": null,
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": null,
      "city": "Bucuresti",
      "address_1": null,
      "address_2": null,
      "zip": null,
      "other_info": [],
      "conta_cont_analitic_client": null,
      "logo_url": null,
      "is_branch": false,
      "cui_branch": null,
      "parent_company": null,
      "subscription_until": null,
      "created_at": "2026-10-29 12:53:43"
    },
    "anaf": {
      "state": null,
      "state_text": null,
      "state_date": null,
      "synced_at": null
    },
    "efactura": {
      "connected": false,
      "expires_at": null,
      "autoupload": false,
      "autodownload": false
    },
    "branches": [],
    "modules": [],
    "preferences": {
      "export_documents": null,
      "spv_alerts": null,
      "spv_downloads_email": null,
      "spv_max_days_send": 1,
      "autosend_invoice_to_client": false,
      "invoice_payments_on_documents": false,
      "invoice_notes": null,
      "invoice_due_date": 15
    }
  }
}

Clienți

Clienții companiei: căutare, creare și actualizare. Nu există ștergere prin API. Documentele pot primi fie client_id, fie clientul inline (client), cu aceleași câmpuri ca aici.

Creează persoană juridică

POST /api/v6/clients

Creează un client persoană juridică.

  • Dacă există deja un client PJ cu același CUI, nu se creează un duplicat: răspunsul conține clientul existent, nemodificat (folosește PATCH pentru a-l actualiza). Poți apela deci acest endpoint ca „găsește sau creează”.
  • Pentru un CUI nou, datele lipsă (denumire, Reg. Com., adresă, plătitor de TVA) se completează din ANAF; valorile trimise de tine au prioritate.

Body

Câmp Tip Obligatoriu Detalii
is_pf bool recomandat false persoană juridică, true persoană fizică. Implicit true la creare.
company string nu Denumirea firmei sau numele persoanei.
vat string da la PJ CUI (cu sau fără RO; se păstrează doar cifrele) sau CNP la persoana fizică. În România CUI-ul și CNP-ul sunt validate. PF fără CNP → CNP anonim 0000000000000.
has_vat bool nu Plătitor de TVA. La PJ se completează din ANAF dacă nu e trimis.
reg string nu Nr. Registrul Comerțului.
country string da Codul țării (RO), din Nomenclatoare > Clienți.
state string nu Codul județului (B, CJ ...), din Nomenclatoare > Județe.
city string nu Localitatea. Pentru București (state: B) este obligatoriu și trebuie să fie Sector 1 ... Sector 6.
address_line_1 string nu Adresa (stradă, număr).
address_line_2 string nu Completare adresă.
zip string nu Cod poștal.
phone string nu Telefon.
email string nu Emailul folosit implicit la trimiterea documentelor (mai multe adrese separate prin virgulă).
bank string nu Banca.
iban string nu IBAN.

Răspuns: statusMessage Client creat cu succes pentru un client nou. Dacă firma are deja un client PJ cu același CUI, răspunsul este tot HTTP 200, cu aceeași structură data, clientul existent rămâne nemodificat, iar statusMessage este Clientul exista deja cu acest cod fiscal si nu a fost modificat.

data (client): id, company, is_pf, has_vat, vat (doar cifre), country (code, name) / null, state (code, name) / null, city, email, address_1, phone, bank, iban.

Erori — 422 Eroare validare client: <motiv>, de exemplu:

  • Denumirea tarii este obligatorie pentru tipul de client selectat.
  • Campul vat este obligatoriu. (PJ fără CUI) / Codul fiscal (vat) nu este valid (CUI românesc invalid) / CNP-ul introdus este invalid
  • Pentru Bucuresti, campul city este obligatoriu si trebuie sa fie Sector 1, Sector 2, ... sau Sector 6.
  • Judet/localitate invalid.
curl -X POST 'https://webill.ro/api/v6/clients' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "is_pf": false,
  "company": "EXEMPLU DISTRIBUTIE SRL",
  "vat": "RO10000008",
  "has_vat": true,
  "reg": "J40/1234/2024",
  "country": "RO",
  "state": "B",
  "city": "Sector 1",
  "address_line_1": "Str. Exemplu nr. 1",
  "address_line_2": "Et. 2, ap. 5",
  "zip": "010101",
  "phone": "0722000000",
  "email": "[email protected]",
  "bank": "Banca Exemplu",
  "iban": "RO49AAAA1B31007593840000"
}'
{
  "status": 200,
  "statusMessage": "Client creat cu succes",
  "data": {
    "id": 2,
    "company": "EXEMPLU DISTRIBUTIE SRL",
    "is_pf": false,
    "has_vat": true,
    "vat": "10000008",
    "country": {
      "code": "RO",
      "name": "Romania"
    },
    "state": {
      "code": "B",
      "name": "Bucuresti"
    },
    "city": "Sector 1",
    "email": "[email protected]",
    "address_1": "Str. Exemplu nr. 1",
    "phone": "0722000000",
    "bank": "Banca Exemplu",
    "iban": "RO49AAAA1B31007593840000"
  }
}

Creează persoană fizică

POST /api/v6/clients

Creează un client persoană fizică (is_pf: true). CNP-ul (vat) este opțional: fără el se folosește CNP-ul anonim 0000000000000, acceptat de e-Factura. Persoanele fizice nu sunt deduplicate: fiecare cerere creează un client nou — caută-l întâi după CNP dacă ai unul.

Câmpurile și erorile sunt cele de la persoana juridică.

data (client): id, company, is_pf, has_vat, vat (doar cifre), country (code, name) / null, state (code, name) / null, city, email, address_1, phone, bank, iban.

curl -X POST 'https://webill.ro/api/v6/clients' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "is_pf": true,
  "company": "Popescu Ana",
  "country": "RO",
  "state": "CJ",
  "city": "Cluj-Napoca",
  "address_line_1": "Str. Memorandumului nr. 10",
  "phone": "0744000000",
  "email": "[email protected]"
}'
{
  "status": 200,
  "statusMessage": "Client creat cu succes",
  "data": {
    "id": 3,
    "company": "Popescu Ana",
    "is_pf": true,
    "has_vat": false,
    "vat": "0000000000000",
    "country": {
      "code": "RO",
      "name": "Romania"
    },
    "state": null,
    "city": "Cluj-Napoca",
    "email": "[email protected]",
    "address_1": "Str. Memorandumului nr. 10",
    "phone": "0744000000",
    "bank": null,
    "iban": null
  }
}

Listă

GET /api/v6/clients

Lista paginată a clienților, ordonată după denumire.

Query

  • q — caută în denumire.
  • per_page — 1–100 (implicit 20); page — pagina (de la 1).
  • id — un singur client (404 Client inexistent dacă nu există).
  • vat — caută după CUI / CNP (vezi cererea următoare).

Răspuns: items[] (clienți, ca la Detaliu) și meta (page, perPage, total, path). Numărul de pagini = ceil(total / perPage).

curl 'https://webill.ro/api/v6/clients?per_page=20&page=1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "company": "CLIENT DEMO SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "23010836",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "AB",
          "name": "Alba"
        },
        "city": "Alba Iulia",
        "email": "[email protected]",
        "address_1": "Str. Principala 1",
        "phone": "0722000000",
        "bank": null,
        "iban": null
      },
      {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 1",
        "phone": "0722000000",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      {
        "id": 3,
        "company": "Popescu Ana",
        "is_pf": true,
        "has_vat": false,
        "vat": "0000000000000",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": null,
        "city": "Cluj-Napoca",
        "email": "[email protected]",
        "address_1": "Str. Memorandumului nr. 10",
        "phone": "0744000000",
        "bank": null,
        "iban": null
      }
    ],
    "meta": {
      "page": 1,
      "perPage": 20,
      "total": 3,
      "path": "http://127.0.0.1:8765/api/v6/clients"
    }
  }
}

Caută după CUI/CNP

GET /api/v6/clients

Caută clientul după cod fiscal sau CNP. Prefixul RO și orice alt caracter în afara cifrelor sunt ignorate. Răspunsul are același format ca lista: items cu cel mult un client (total: 0 și items: [] dacă nu există).

Tipic pentru integrare: caută după CUI → dacă nu există, creează-l (sau trimite direct clientul inline pe factură).

Parametri în URL

ParametruDescriere
vat

CUI / CNP, cu sau fără RO.

curl 'https://webill.ro/api/v6/clients?vat=10000008' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "items": [
      {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 1",
        "phone": "0722000000",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      }
    ],
    "meta": {
      "page": 1,
      "perPage": 1,
      "total": 1,
      "path": "http://127.0.0.1:8765/api/v6/clients"
    }
  }
}

Detaliu

GET /api/v6/clients/{client_id}

Un client după ID. data este direct obiectul client.

data (client): id, company, is_pf, has_vat, vat (doar cifre), country (code, name) / null, state (code, name) / null, city, email, address_1, phone, bank, iban.

Erori: 404 Clientul nu a fost gasit.

curl 'https://webill.ro/api/v6/clients/1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "id": 2,
    "company": "EXEMPLU DISTRIBUTIE SRL",
    "is_pf": false,
    "has_vat": true,
    "vat": "10000008",
    "country": {
      "code": "RO",
      "name": "Romania"
    },
    "state": {
      "code": "B",
      "name": "Bucuresti"
    },
    "city": "Sector 1",
    "email": "[email protected]",
    "address_1": "Str. Exemplu nr. 1",
    "phone": "0722000000",
    "bank": "Banca Exemplu",
    "iban": "RO49AAAA1B31007593840000"
  }
}

Actualizează

PATCH /api/v6/clients/{client_id}

Actualizează doar câmpurile trimise (aceleași câmpuri ca la creare); restul rămân neschimbate. Validarea se face pe clientul rezultat (de ex. un client din București trebuie să aibă în continuare city = Sector N). Nu se face completare din ANAF.

Răspuns: statusMessage Client actualizat, data = clientul.

Erori: 404 Clientul nu a fost gasit; 422 Eroare validare client: ....

curl -X PATCH 'https://webill.ro/api/v6/clients/1' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "phone": "0722999999",
  "email": "[email protected]",
  "address_line_1": "Str. Exemplu nr. 3"
}'
{
  "status": 200,
  "statusMessage": "Client actualizat",
  "data": {
    "id": 2,
    "company": "EXEMPLU DISTRIBUTIE SRL",
    "is_pf": false,
    "has_vat": true,
    "vat": "10000008",
    "country": {
      "code": "RO",
      "name": "Romania"
    },
    "state": {
      "code": "B",
      "name": "Bucuresti"
    },
    "city": "Sector 1",
    "email": "[email protected]",
    "address_1": "Str. Exemplu nr. 3",
    "phone": "0722999999",
    "bank": "Banca Exemplu",
    "iban": "RO49AAAA1B31007593840000"
  }
}

Proiecte

Proiectele companiei și pontajul zilnic pe proiect (pentru aplicații de time-tracking). Orele pontate se facturează din WeBill.

Listă

GET /api/v6/projects

Toate proiectele companiei, cele mai noi primele (fără paginare).

projects[]: id, project_name, status (working activ, standby pauză, draft ciornă, completed finalizat, canceled anulat), client_id, client (id, company) / null, currency, default_price_per_hour, estimative_price, deadline.

curl 'https://webill.ro/api/v6/projects' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Proiecte",
  "data": {
    "projects": [
      {
        "id": 1,
        "project_name": "Implementare magazin online",
        "status": "working",
        "client_id": 1,
        "client": {
          "id": 1,
          "company": "CLIENT DEMO SRL"
        },
        "currency": "RON",
        "default_price_per_hour": 150,
        "estimative_price": 6000,
        "deadline": null
      }
    ]
  }
}

Pontaj zilnic

POST /api/v6/projects/{project_id}/timesheets

Înregistrează timpul lucrat într-o zi pe un proiect. Există un singur pontaj pe proiect și zi: a doua cerere pentru aceeași zi îl suprascrie (200), prima îl creează (201).

Body

Câmp Tip Obligatoriu Detalii
job_date AAAA-LL-ZZ da Ziua lucrată.
job_time H:MM / HH:MM / HH:MM:SS da Durata lucrată (nu ora din zi), ex. 2:30 = 2 ore și 30 de minute.
job_notes string da Ce s-a lucrat.
billable bool nu Se facturează. Implicit true (și la suprascriere, dacă lipsește).
status int nu 0 To Do, 2 In Progress, 5 In review (implicit), 1 Done, 3 On Hold, 4 Canceled.
created_by int nu ID-ul utilizatorului WeBill care a lucrat.

Tariful orar este întotdeauna default_price_per_hour al proiectului.

Răspuns: id, project_id, job_date, job_time, job_timespan (minute), job_notes, billable, status, price_per_hour, created_by.

Erori: 404 Proiectul nu a fost gasit (inexistent sau al altei companii); 422 Date invalide la pontaj cu errors pe câmpuri.

curl -X POST 'https://webill.ro/api/v6/projects/1/timesheets' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "job_date": "2026-11-13",
  "job_time": "2:30",
  "job_notes": "Integrare API facturare",
  "billable": true,
  "status": 5
}'
{
  "status": 201,
  "statusMessage": "success",
  "data": {
    "id": 1,
    "project_id": 1,
    "job_date": "2026-10-29",
    "job_time": "2:30:00",
    "job_timespan": 150,
    "job_notes": "Integrare API facturare",
    "billable": true,
    "status": 5,
    "price_per_hour": 150,
    "created_by": 1
  }
}

Facturi fiscale

Facturi fiscale: emitere, modificare, PDF, email, încasări, anulare și stornare. Cererile sunt în ordinea în care pot fi rulate cap-coadă (Collection Runner); fiecare creare salvează ID-ul în Environment.

Creează

POST /api/v6/invoices

Emite o factură fiscală emisă, numerotată în seria aleasă (API-ul nu creează ciorne). Transmiterea în SPV (e-Factura) se face din WeBill, după setările companiei.

Cu modulul Gestiune pornit, liniile cu produse urmărite pe stoc descarcă stocul din gestiunea implicită, din loturile cele mai vechi (API-ul nu primește gestiunea sau lotul). Stoc insuficient → 422 Stoc insuficient pentru "..." in gestiunea "...", la AAAA-LL-ZZ: disponibil X, necesar Y., iar factura nu se creează.

Body

Câmp Tip Obligatoriu Detalii
client_id int unul din client_id / client Client existent al companiei (vezi Clienți).
client obiect unul din client_id / client Client inline, cu aceleași câmpuri și reguli ca POST /clients (persoana juridică existentă cu același CUI este refolosită). Eroare → 422 Client invalid: ....
items array da Cel puțin o linie (vezi mai jos).
serie_id int nu Seria (Nomenclatoare > Facturi: invoice_series / proforma_series). Implicit seria marcată „Implicită” în Setări, altfel prima serie activă. Serie străină / inactivă → 422 INVALID_INVOICE_SERIE / INVALID_PROFORMA_SERIE.
delegate_id int nu Delegatul (delegates). Implicit delegatul marcat „Implicit” în Setări, altfel primul delegat activ. → 422 INVALID_DELEGATE.
bank_accounts int[] nu Conturile bancare tipărite pe document (banks). Implicit contul marcat „Implicit” în moneda documentului, altfel toate conturile active. → 422 INVALID_BANK_ACCOUNT.
issue_date AAAA-LL-ZZ nu Data documentului; implicit azi. O factură nu poate fi datată înaintea ultimei facturi emise din aceeași serie (422).
due_days / due_date int ≥ 0 sau dată nu Termenul de plată: numărul de zile (implicit 15) sau direct data scadenței, AAAA-LL-ZZ (sau ZZ.LL.AAAA), care nu poate fi înaintea datei documentului.
currency string (3) nu Implicit RON. Lista în Nomenclatoare > Facturi (currencies).
exchange_rate număr nu Implicit cursul BNR al datei documentului (1 pentru RON).
language ro / en nu Limba documentului (PDF, email). Implicit ro.
comments string nu Observații tipărite pe document.
document_type int nu Tipul e-Factura: 380 factură (implicit), 751 factură în scop de informare contabilă, 389 autofactură (emisă în numele furnizorului: clientul documentului e furnizorul, compania e cumpărătorul).
order_id string nu ID-ul comenzii din sistemul tău. Idempotență: o factură pentru același client și același order_id creată în ultimele 2 minute este întoarsă în loc să se creeze un duplicat (sigur la reîncercări după timeout). Două cereri simultane cu același order_id → a doua primește 409 Comanda este deja in curs de facturare. Reincearca.
curier, awb string nu Date de livrare.
generate_payment_link bool nu true generează un link de plată cu cardul (Netopia) inclus în email și PDF. Cere un cont Netopia activ în companie, altfel 400.

Linii (items[])

Câmp Tip Obligatoriu Detalii
description string ≤ 255 da* Denumirea produsului / serviciului.
details string nu Text suplimentar pe linie.
um string ≤ 50 da* Unitatea de măsură: denumirea folosită de companie (ex. BUC, ORA) sau codul UN/ECE (H87, HUR). Lista: Nomenclatoare > Facturi (units).
qty număr > 0 da Cantitatea. Zecimale cu punct sau virgulă.
unit_price număr ≥ 0 da* Prețul unitar, în moneda liniei.
tax_included bool nu Implicit true: prețul include TVA. false = preț fără TVA.
tax_value număr 0–100 nu Cota TVA în procente (ex. 21, 11, 0). Se potrivește cu o cotă activă a companiei cu exact acest procent; vezi taxes din Nomenclatoare > Facturi.
tax_id int nu ID-ul cotei TVA din Nomenclatoare > Facturi. Are prioritate față de tax_value. Cotă inexistentă / inactivă → 422 INVALID_TAX.
discount număr nu Reducere pe linie, ca valoare (în moneda liniei).
discount_type string nu Doar valoric (implicit). Reducerea procentuală nu este disponibilă prin API.
currency string (3) nu Moneda liniei; implicit moneda documentului. Conversia se face la cursul BNR al datei documentului.
product_id int nu Produs din Nomenclatoare > Produse și servicii: câmpurile netrimise (description, details, um, unit_price, currency, tax_id, tax_included, cpv_code) se completează din produs. Produs inexistent → 422 INVALID_PRODUCT.
cpv_code string nu Cod CPV (achiziții publice).

* nu sunt obligatorii când linia are product_id. O cantitate, un preț sau o reducere negativă marchează linia ca linie de stornare.

Exemplu de calcul (body-ul de mai jos): linia 1 are prețul cu TVA inclus (1000 = 826,45 + 173,55 TVA); linia 2 are prețul fără TVA: 2 × 150 − 30 reducere = 270 + 56,70 TVA. Totalurile sunt în totals.

Răspuns: statusMessage Document creat.

data (document)

  • id, document_type (invoice / proforma), company_id, serie_id, serie, number, number_display (ex. WB000012).
  • date (AAAA-LL-ZZ), due_days, due_date (ZZ.LL.AAAA, păstrat așa pentru integrările existente), due_date_iso (aceeași zi, AAAA-LL-ZZ), currency, exchange_rate, language, efactura_type (380 / 751 / 389 / 100).
  • status: emisa, anulata, storno (factura inversă a unei stornări).
  • status_incasare: pending (neîncasată), partial, incasata, compensata (închisă din credit / stornare parțială), stornata.
  • client: obiectul client (ca la Clienți > Detaliu).
  • totals.items[]: liniile — id (folosit la stornare), denumire, nota, um, um_code, qty, cota_tva, pret_cu_tva, pret_fara_tva, valoare (fără TVA), tva, discount, discount_net, discount_tva, cpv_code.
  • totals.subtotal: pe cota TVA ("21": {"total_fara_tva", "total_tva"}); totals.total: valoare (fără TVA) și tva sunt înainte de reduceri, total (de plată) este după reduceri: total = valoare + tva - discount.total; totals.discount: reducerile; totals.stats: incasat, rest (rest de plată).
  • items_count, payment_link_requested, payment_link (linkul de plată Netopia activ sau null).

Erori

  • 400 Payload JSON invalid: ... — corpul nu este JSON valid.
  • 422 Date invalide la linii, cu erorile în errors pe cheia liniei (ex. {"items.0.description": ["Campul description este obligatoriu."]}); la fel pentru items: [].
  • 422 Data din campul issue_date nu este valida (format AAAA-LL-ZZ). (sau date, după câmpul trimis) — o dată pe care serverul nu o poate citi nu mai devine data de azi.
  • 422 pentru un due_date care nu e nici număr de zile, nici dată, sau care e înaintea datei documentului.
  • 422 Clientul nu a fost identificat — lipsește client_id / client sau clientul nu este al companiei.
  • 422 Date invalide la document + errors pe câmpuri (ex. errors.items).
  • 422 cu errors.code: INVALID_INVOICE_SERIE, INVALID_PROFORMA_SERIE, INVALID_DELEGATE, INVALID_BANK_ACCOUNT, INVALID_TAX, INVALID_TAX_CLIENT (cotă de taxare inversă / intracomunitară nepotrivită clientului), INVALID_PRODUCT, INVALID_CLIENT, INVALID_ITEMS.
  • 422 Data facturii (...) nu poate fi inaintea ultimei facturi emise din seria ... (errors.issue_date).
  • 409 Comanda este deja in curs de facturare. Reincearca. — altă cerere cu același order_id este în curs.
  • 400 Compania nu are un cont Netopia activ pentru generarea linkului de plata.
curl -X POST 'https://webill.ro/api/v6/invoices' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client_id": 1,
  "serie_id": 1,
  "delegate_id": 1,
  "bank_accounts": [
    1
  ],
  "issue_date": "2026-11-13",
  "due_days": 15,
  "currency": "RON",
  "language": "ro",
  "document_type": 380,
  "order_id": "WC-1700000000",
  "comments": "Comanda online WC-1001",
  "generate_payment_link": false,
  "items": [
    {
      "description": "Abonament platformă",
      "details": "Luna curentă",
      "um": "BUC",
      "qty": 1,
      "unit_price": 1000,
      "tax_included": true,
      "tax_value": 21
    },
    {
      "description": "Licență utilizator suplimentar",
      "um": "BUC",
      "qty": 2,
      "unit_price": 150,
      "tax_included": false,
      "tax_value": 21,
      "discount": 30,
      "discount_type": "valoric"
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Document creat",
  "data": {
    "id": 1,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 1,
    "number_display": "WB000001",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 1,
          "sort_order": 1,
          "type": 1,
          "denumire": "Abonament platformă",
          "nota": "Luna curentă",
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 1000,
          "pret_fara_tva": 826.45,
          "valoare": 826.45,
          "tva": 173.55,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        },
        {
          "id": 2,
          "sort_order": 2,
          "type": 1,
          "denumire": "Licență utilizator suplimentar",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 2,
          "cota_tva": 21,
          "pret_cu_tva": 181.5,
          "pret_fara_tva": 150,
          "valoare": 300,
          "tva": 63,
          "discount": 36.3,
          "discount_net": 30,
          "discount_tva": 6.3,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 1096.45,
          "total_tva": 230.25
        }
      },
      "total": {
        "valoare": 1126.45,
        "tva": 236.55,
        "total": 1326.7
      },
      "discount": {
        "valoare": 30,
        "tva": 6.3,
        "total": 36.3
      },
      "stats": {
        "incasat": 0,
        "rest": 1326.7
      }
    },
    "items_count": 2,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Creează minimă

POST /api/v6/invoices

Cea mai scurtă factură validă: clientul și liniile. Seria, delegatul, conturile bancare, data (azi), termenul (15 zile), moneda (RON) și limba (ro) iau valorile implicite ale companiei; o linie fără tax_value / tax_id primește cota implicită.

Câmpurile sunt descrise la Creează.

curl -X POST 'https://webill.ro/api/v6/invoices' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client_id": 1,
  "items": [
    {
      "description": "Mentenanță lunară",
      "um": "BUC",
      "qty": 1,
      "unit_price": 121,
      "tax_value": 21
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Document creat",
  "data": {
    "id": 2,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 2,
    "number_display": "WB000002",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 3,
          "sort_order": 1,
          "type": 1,
          "denumire": "Mentenanță lunară",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 121,
          "pret_fara_tva": 100,
          "valoare": 100,
          "tva": 21,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 100,
          "total_tva": 21
        }
      },
      "total": {
        "valoare": 100,
        "tva": 21,
        "total": 121
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 121
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Creează cu client inline

POST /api/v6/invoices

Factură cu clientul trimis direct în client (fără să-l creezi întâi): clientul PJ existent cu același CUI este refolosit, altfel se creează. Util pentru magazinele online. Câmpurile clientului sunt cele de la Clienți > Creează; pentru o persoană fizică fără CNP trimite is_pf: true fără vat.

Folosește product_id (din Nomenclatoare > Produse): linia se completează din nomenclator.

Erori în plus față de Creează: 422 Client invalid: <motiv>.

curl -X POST 'https://webill.ro/api/v6/invoices' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client": {
    "is_pf": false,
    "company": "EXEMPLU DISTRIBUTIE SRL",
    "vat": "RO10000008",
    "country": "RO",
    "state": "B",
    "city": "Sector 1",
    "address_line_1": "Str. Exemplu nr. 1",
    "email": "[email protected]"
  },
  "order_id": "WC-1700000000-2",
  "items": [
    {
      "product_id": 1,
      "qty": 1
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Document creat",
  "data": {
    "id": 3,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 3,
    "number_display": "WB000003",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 4,
          "sort_order": 1,
          "type": 1,
          "denumire": "Abonament lunar",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 121,
          "pret_fara_tva": 100,
          "valoare": 100,
          "tva": 21,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 100,
          "total_tva": 21
        }
      },
      "total": {
        "valoare": 100,
        "tva": 21,
        "total": 121
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 121
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Creează cu încasare card

POST /api/v6/invoices/with-receipt

Emite factura și o încasează în aceeași cerere, într-o singură tranzacție: dacă încasarea e invalidă, factura nu se creează. Potrivit pentru comenzile deja plătite online.

Body: câmpurile de la Creează plus receipt (obligatoriu), cu câmpurile de la Încasări - Creează (type, amount, date, identifier, serie_id, notes).

Răspuns: statusMessage Document si incasare create; data = factura (ca la Creează) plus cheia receipt (încasarea).

Erori în plus: 422 Date invalide la incasare (errors.receipt: Obiectul receipt este obligatoriu., sau erori pe câmpurile încasării); 422 INVOICE_PAYMENT_AMOUNT_INVALID.

curl -X POST 'https://webill.ro/api/v6/invoices/with-receipt' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client": {
    "is_pf": false,
    "company": "EXEMPLU DISTRIBUTIE SRL",
    "vat": "RO10000008",
    "country": "RO",
    "state": "B",
    "city": "Sector 1",
    "address_line_1": "Str. Exemplu nr. 1",
    "email": "[email protected]"
  },
  "issue_date": "2026-11-13",
  "currency": "RON",
  "order_id": "CARD-1700000000",
  "comments": "Comanda achitata online",
  "items": [
    {
      "description": "Produs achitat online",
      "um": "BUC",
      "qty": 1,
      "unit_price": 242,
      "tax_included": true,
      "tax_value": 21
    }
  ],
  "receipt": {
    "type": "card",
    "identifier": "TX-1700000000",
    "amount": 242,
    "date": "2026-11-13",
    "notes": "Plata card confirmata"
  }
}'
{
  "status": 200,
  "statusMessage": "Document si incasare create",
  "data": {
    "id": 4,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 4,
    "number_display": "WB000004",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "incasata",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 5,
          "sort_order": 1,
          "type": 1,
          "denumire": "Produs achitat online",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 242,
          "pret_fara_tva": 200,
          "valoare": 200,
          "tva": 42,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 200,
          "total_tva": 42
        }
      },
      "total": {
        "valoare": 200,
        "tva": 42,
        "total": 242
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 242,
        "rest": 0
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null,
    "receipt": {
      "id": 1,
      "invoice_id": 4,
      "type": "card",
      "identifier": "TX-1793271228",
      "serie_id": null,
      "serie": null,
      "number": null,
      "receipt_number": "TX-1793271228",
      "date": "2026-10-29",
      "amount": 242,
      "notes": "Plata card confirmata",
      "created_at": "2026-10-29 12:53:48",
      "updated_at": "2026-10-29 12:53:48"
    }
  }
}

Actualizează

PATCH /api/v6/invoices/{invoice_id}

Modifică o factură emisă care nu a fost trimisă în SPV. Se schimbă doar câmpurile trimise (cele de la Creează, plus status).

  • client_id (sau client) e opțional: fără el factura își păstrează clientul; trimis, schimbă clientul.
  • items, dacă e trimis, înlocuiește toate liniile facturii.
  • status: emisa, anulata, storno, doar prin tranzițiile permise; pentru anulare și stornare folosește endpointurile dedicate.

Răspuns: statusMessage Document actualizat, data = factura.

Erori

  • 404 Documentul nu a fost gasit.
  • 409 Factura nu mai poate fi modificata. (errors.invoice) — factura a fost trimisă în SPV sau este blocată de o stornare parțială / factură de corecție / reducere. Corecția se face prin stornare.
  • 422 Clientul nu a fost identificat — client_id trimis nu este un client al companiei.
  • celelalte erori de la Creează.
curl -X PATCH 'https://webill.ro/api/v6/invoices/1' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client_id": 1,
  "curier": "Fan Courier",
  "awb": "2345678901",
  "comments": "Livrare prin curier"
}'
{
  "status": 200,
  "statusMessage": "Document actualizat",
  "data": {
    "id": 1,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 1,
    "number_display": "WB000001",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 1,
          "sort_order": 1,
          "type": 1,
          "denumire": "Abonament platformă",
          "nota": "Luna curentă",
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 1000,
          "pret_fara_tva": 826.45,
          "valoare": 826.45,
          "tva": 173.55,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        },
        {
          "id": 2,
          "sort_order": 2,
          "type": 1,
          "denumire": "Licență utilizator suplimentar",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 2,
          "cota_tva": 21,
          "pret_cu_tva": 181.5,
          "pret_fara_tva": 150,
          "valoare": 300,
          "tva": 63,
          "discount": 36.3,
          "discount_net": 30,
          "discount_tva": 6.3,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 1096.45,
          "total_tva": 230.25
        }
      },
      "total": {
        "valoare": 1126.45,
        "tva": 236.55,
        "total": 1326.7
      },
      "discount": {
        "valoare": 30,
        "tva": 6.3,
        "total": 36.3
      },
      "stats": {
        "incasat": 0,
        "rest": 1326.7
      }
    },
    "items_count": 2,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Detaliu

GET /api/v6/invoices/{invoice_id}

Factura, cu clientul, totalurile pe cote de TVA, liniile (totals.items) și situația încasării (totals.stats.incasat, totals.stats.rest).

data (document)

  • id, document_type (invoice / proforma), company_id, serie_id, serie, number, number_display (ex. WB000012).
  • date (AAAA-LL-ZZ), due_days, due_date (ZZ.LL.AAAA, păstrat așa pentru integrările existente), due_date_iso (aceeași zi, AAAA-LL-ZZ), currency, exchange_rate, language, efactura_type (380 / 751 / 389 / 100).
  • status: emisa, anulata, storno (factura inversă a unei stornări).
  • status_incasare: pending (neîncasată), partial, incasata, compensata (închisă din credit / stornare parțială), stornata.
  • client: obiectul client (ca la Clienți > Detaliu).
  • totals.items[]: liniile — id (folosit la stornare), denumire, nota, um, um_code, qty, cota_tva, pret_cu_tva, pret_fara_tva, valoare (fără TVA), tva, discount, discount_net, discount_tva, cpv_code.
  • totals.subtotal: pe cota TVA ("21": {"total_fara_tva", "total_tva"}); totals.total: valoare (fără TVA) și tva sunt înainte de reduceri, total (de plată) este după reduceri: total = valoare + tva - discount.total; totals.discount: reducerile; totals.stats: incasat, rest (rest de plată).
  • items_count, payment_link_requested, payment_link (linkul de plată Netopia activ sau null).

Erori: 404 Factura nu a fost gasita.

curl 'https://webill.ro/api/v6/invoices/1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "id": 1,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 1,
    "number_display": "WB000001",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 1,
          "sort_order": 1,
          "type": 1,
          "denumire": "Abonament platformă",
          "nota": "Luna curentă",
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 1000,
          "pret_fara_tva": 826.45,
          "valoare": 826.45,
          "tva": 173.55,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        },
        {
          "id": 2,
          "sort_order": 2,
          "type": 1,
          "denumire": "Licență utilizator suplimentar",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 2,
          "cota_tva": 21,
          "pret_cu_tva": 181.5,
          "pret_fara_tva": 150,
          "valoare": 300,
          "tva": 63,
          "discount": 36.3,
          "discount_net": 30,
          "discount_tva": 6.3,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 1096.45,
          "total_tva": 230.25
        }
      },
      "total": {
        "valoare": 1126.45,
        "tva": 236.55,
        "total": 1326.7
      },
      "discount": {
        "valoare": 30,
        "tva": 6.3,
        "total": 36.3
      },
      "stats": {
        "incasat": 0,
        "rest": 1326.7
      }
    },
    "items_count": 2,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Caută după serie și număr

GET /api/v6/invoices/find

Factura fiscală cu seria și numărul date, confirmată de codul fiscal al emitentului și, opțional, de dată și de client, în compania tokenului: același răspuns ca la Detaliu (GET /invoices/{id}). Util când sistemul tău a păstrat numărul tipărit, nu ID-ul WeBill.

Exact sau nimic. Căutarea nu ghicește: dacă ceva nu corespunde întocmai sau mai multe documente se potrivesc, primești o eroare, niciodată documentul „cel mai probabil”. O automatizare care acționează pe răspuns (încasare, stornare) nu poate atinge astfel o factură greșită.

Query (serie, number și company_vat obligatorii; restul opționale, fiecare trimis se compară)

Parametru Detalii
serie Seria, ex. WB.
number Numărul: doar cifre (12, 0012) sau numărul tipărit cu seria în față (WB0012). Orice altceva (12a, WB-12, altă serie) → 400.
company_vat CUI-ul emitentului, cum apare pe document (pentru un punct de lucru, al companiei-mamă). Se acceptă cu sau fără RO, cu spații.
date Opțional. Data documentului, AAAA-LL-ZZ. Deosebește documentele vechi cu aceeași serie și același număr.
client_vat Opțional. CUI-ul / CNP-ul clientului cum a fost tipărit la emitere (o schimbare ulterioară a clientului nu contează). Cu sau fără RO; un cod străin își păstrează prefixul țării (DE123...). La persoanele fizice fără CNP (0000000000000) codul nu identifică pe nimeni: lasă-l gol sau folosește date.
client_name Opțional. Numele clientului de pe document, comparat fără majuscule, diacritice și spații în plus.
Răspuns errors.code Când
200 — Exact un document se potrivește.
400 — Lipsește un parametru obligatoriu, number nu este exact numărul documentului sau date nu e o dată AAAA-LL-ZZ.
404 DOCUMENT_NOT_FOUND Nu există niciun document cu seria și numărul acestea (Factura nu a fost gasita).
404 COMPANY_MISMATCH Documentul există, dar emitentul are alt cod fiscal (ex. tokenul altei companii).
404 DATE_MISMATCH Documentul există, dar are altă dată.
404 CLIENT_MISMATCH Documentul există, dar clientul are alt cod fiscal sau alt nume.
409 AMBIGUOUS_DOCUMENT Mai multe documente se potrivesc (aceeași serie și același număr, fără date sau client care să le deosebească) (ex. o factură veche și stornarea ei cu același număr). errors.candidates[] are id, date, status: alege documentul și cere-l cu GET /invoices/{id}.

Proformele nu sunt căutate aici (au proforme/find). Ciornele nu au număr, deci nu se găsesc.

curl 'https://webill.ro/api/v6/invoices/find?serie=WB&number=1&company_vat=10000008&client_vat=10000008' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "id": 1,
    "document_type": "invoice",
    "company_id": 1,
    "serie_id": 1,
    "serie": "WB",
    "number": 1,
    "number_display": "WB000001",
    "date": "2026-10-29",
    "due_days": 15,
    "due_date": "13.11.2026",
    "due_date_iso": "2026-11-13",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 380,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 1,
          "sort_order": 1,
          "type": 1,
          "denumire": "Abonament platformă",
          "nota": "Luna curentă",
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 1000,
          "pret_fara_tva": 826.45,
          "valoare": 826.45,
          "tva": 173.55,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        },
        {
          "id": 2,
          "sort_order": 2,
          "type": 1,
          "denumire": "Licență utilizator suplimentar",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 2,
          "cota_tva": 21,
          "pret_cu_tva": 181.5,
          "pret_fara_tva": 150,
          "valoare": 300,
          "tva": 63,
          "discount": 36.3,
          "discount_net": 30,
          "discount_tva": 6.3,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 1096.45,
          "total_tva": 230.25
        }
      },
      "total": {
        "valoare": 1126.45,
        "tva": 236.55,
        "total": 1326.7
      },
      "discount": {
        "valoare": 30,
        "tva": 6.3,
        "total": 36.3
      },
      "stats": {
        "incasat": 0,
        "rest": 1326.7
      }
    },
    "items_count": 2,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Descarcă PDF

GET /api/v6/invoices/{invoice_id}/download

PDF-ul documentului. Răspunsul este fișierul (Content-Type: application/pdf, Content-Disposition: attachment; filename=factura-fiscala-wb000012-09-10-2026.pdf).

Erori (JSON): 404 Documentul nu a fost gasit.

curl 'https://webill.ro/api/v6/invoices/1/download' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -o document.pdf

Răspunsul este fișierul, nu JSON:

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename=factura-fiscala-wb000001-29-10-2026.pdf
  • X-RateLimit-Limit: 120
  • X-RateLimit-Remaining: 119

Trimite pe email

POST /api/v6/invoices/{invoice_id}/email

Trimite documentul pe email, cu PDF-ul atașat. Trimiterea se face asincron (în coadă), deci răspunsul confirmă programarea, nu livrarea. Fiecare trimitere apare în istoricul de emailuri al documentului din WeBill (sursa API), la facturi și la proforme.

Body (toate opționale)

Câmp Tip Obligatoriu Detalii
to string nu Destinatarul. Implicit emailul clientului (prima adresă validă; celelalte trec în CC).
cc string nu Adrese în copie, separate prin , sau ;.
subject string nu Subiectul. Implicit Factura fiscala #WB000012 / Factura proforma #PF000003.

Răspuns: statusMessage Email programat pentru trimitere, data: document_id, recipient.

Erori: 404 Documentul nu a fost gasit; 400 Clientul nu are email setat (fără to și fără email la client).

curl -X POST 'https://webill.ro/api/v6/invoices/1/email' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "to": "[email protected]",
  "cc": "[email protected]",
  "subject": "Factura pentru comanda WC-1001"
}'
{
  "status": 200,
  "statusMessage": "Email programat pentru trimitere",
  "data": {
    "document_id": 1,
    "recipient": "[email protected]"
  }
}

Încasări - Listă

GET /api/v6/invoices/{invoice_id}/receipts

Încasările documentului, ordonate după dată, plus documentul (cu totals.stats.incasat / rest).

Răspuns: statusMessage Incasari document, data: document, receipts[].

data (încasare): id, invoice_id (ID-ul documentului), type, identifier, serie_id, serie, number, receipt_number (ex. CH.1, doar la numerar), date, amount, notes, created_at, updated_at.

curl 'https://webill.ro/api/v6/invoices/1/receipts' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Incasari document",
  "data": {
    "document": {
      "id": 1,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 1,
      "number_display": "WB000001",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "pending",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 1,
            "sort_order": 1,
            "type": 1,
            "denumire": "Abonament platformă",
            "nota": "Luna curentă",
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 1000,
            "pret_fara_tva": 826.45,
            "valoare": 826.45,
            "tva": 173.55,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          },
          {
            "id": 2,
            "sort_order": 2,
            "type": 1,
            "denumire": "Licență utilizator suplimentar",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 2,
            "cota_tva": 21,
            "pret_cu_tva": 181.5,
            "pret_fara_tva": 150,
            "valoare": 300,
            "tva": 63,
            "discount": 36.3,
            "discount_net": 30,
            "discount_tva": 6.3,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 1096.45,
            "total_tva": 230.25
          }
        },
        "total": {
          "valoare": 1126.45,
          "tva": 236.55,
          "total": 1326.7
        },
        "discount": {
          "valoare": 30,
          "tva": 6.3,
          "total": 36.3
        },
        "stats": {
          "incasat": 0,
          "rest": 1326.7
        }
      },
      "items_count": 2,
      "payment_link_requested": false,
      "payment_link": null
    },
    "receipts": []
  }
}

Încasări - Creează

POST /api/v6/invoices/{invoice_id}/receipts

Înregistrează o încasare pe document. Starea de încasare a documentului (status_incasare) se actualizează: pending → partial → incasata. O sumă mai mare decât restul este acceptată; diferența intră în creditul clientului.

Body

Câmp Tip Obligatoriu Detalii
type string da Tipul încasării (tabelul de mai jos).
amount număr > 0 da Suma, în moneda documentului.
date AAAA-LL-ZZ da Data încasării.
identifier string ≤ 255 la op / bf / card / ramburs Referința plății (nr. OP, ID tranzacție, AWB, nr. bon).
serie_id int la cash Seria cu chitanțier (invoice_series[].id din Nomenclatoare > Facturi). Chitanța se numerotează automat.
notes string nu Observații.
type Ce este Câmpuri cerute în plus
op Ordin de plată / transfer bancar identifier (ex. numărul OP)
bf Bon fiscal identifier (numărul bonului)
card Plată cu cardul / POS / online identifier (ex. ID-ul tranzacției)
ramburs Ramburs prin curier identifier (ex. AWB)
cash Numerar, cu chitanță numerotată automat serie_id = ID-ul seriei de facturi care are chitanțierul (invoice_series[].id, câmpul receipt_serie)
avans Avans —
credit Din creditul clientului (sume plătite în plus, stornări) — ; suma nu poate depăși creditul disponibil

Răspuns: statusMessage Incasare creata.

data (încasare): id, invoice_id (ID-ul documentului), type, identifier, serie_id, serie, number, receipt_number (ex. CH.1, doar la numerar), date, amount, notes, created_at, updated_at.

Erori

  • 404 Documentul nu a fost gasit.
  • 422 Date invalide la incasare + errors pe câmpuri (ex. identifier, serie_id).
  • 422 INVOICE_PAYMENT_AMOUNT_INVALID, INVOICE_PAYMENT_TYPE_INVALID, INVALID_RECEIPT_SERIE.
  • 422 Creditul disponibil al clientului este ... RON. (tipul credit).
  • 409 INVOICE_PAYMENT_NOT_ALLOWED — documentul nu mai acceptă încasări (anulat, stornat, proformă convertită).
curl -X POST 'https://webill.ro/api/v6/invoices/1/receipts' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "type": "op",
  "identifier": "OP-1001",
  "amount": 100,
  "date": "2026-11-13",
  "notes": "Plata partiala prin OP"
}'
{
  "status": 200,
  "statusMessage": "Incasare creata",
  "data": {
    "id": 2,
    "invoice_id": 1,
    "type": "op",
    "identifier": "OP-1001",
    "serie_id": null,
    "serie": null,
    "number": null,
    "receipt_number": "OP-1001",
    "date": "2026-10-29",
    "amount": 100,
    "notes": "Plata partiala prin OP",
    "created_at": "2026-10-29 12:53:48",
    "updated_at": "2026-10-29 12:53:48"
  }
}

Încasări - Creează cash

POST /api/v6/invoices/{invoice_id}/receipts

Încasare în numerar: se emite o chitanță numerotată automat în chitanțierul seriei serie_id (receipt_number, ex. CH.1). identifier nu se trimite.

Câmpurile și erorile sunt cele de la Încasări - Creează.

curl -X POST 'https://webill.ro/api/v6/invoices/1/receipts' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "type": "cash",
  "serie_id": 1,
  "amount": 100,
  "date": "2026-11-13",
  "notes": "Achitat la livrare"
}'
{
  "status": 200,
  "statusMessage": "Incasare creata",
  "data": {
    "id": 3,
    "invoice_id": 1,
    "type": "cash",
    "identifier": "CH.1",
    "serie_id": 1,
    "serie": "CH",
    "number": 1,
    "receipt_number": "CH.1",
    "date": "2026-10-29",
    "amount": 100,
    "notes": "Achitat la livrare",
    "created_at": "2026-10-29 12:53:48",
    "updated_at": "2026-10-29 12:53:48"
  }
}

Încasări - Actualizează

PATCH /api/v6/invoices/{invoice_id}/receipts/{receipt_id}

Modifică doar câmpurile trimise: amount, date, identifier, notes. Tipul și seria încasării nu se pot schimba (422 Tipul incasarii nu poate fi modificat.): pentru alt tip, șterge încasarea și creeaz-o din nou.

Răspuns: statusMessage Incasare actualizata, data = încasarea.

Erori: 404 Incasarea nu a fost gasita; 422 Date invalide la incasare; 422 Eroare validare incasare: ... (sumă ≤ 0, încasare creată automat din credit / stornare, factură stornată).

curl -X PATCH 'https://webill.ro/api/v6/invoices/1/receipts/1' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "amount": 150,
  "identifier": "OP-1001",
  "notes": "Suma corectata dupa extras"
}'
{
  "status": 200,
  "statusMessage": "Incasare actualizata",
  "data": {
    "id": 2,
    "invoice_id": 1,
    "type": "op",
    "identifier": "OP-1001",
    "serie_id": null,
    "serie": null,
    "number": null,
    "receipt_number": "OP-1001",
    "date": "2026-10-29",
    "amount": 150,
    "notes": "Suma corectata dupa extras",
    "created_at": "2026-10-29 12:53:48",
    "updated_at": "2026-10-29 12:53:48"
  }
}

Încasări - Descarcă chitanță

GET /api/v6/invoices/{invoice_id}/receipts/{receipt_id}/download

PDF-ul chitanței (încasări cash) sau al dovezii de încasare. Răspunsul este fișierul (Content-Type: application/pdf, Content-Disposition: attachment; filename="Chitanta-CH.1.pdf").

Erori (JSON): 404 Documentul nu a fost gasit / Incasarea nu a fost gasita.

curl 'https://webill.ro/api/v6/invoices/1/receipts/1/download' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -o document.pdf

Răspunsul este fișierul, nu JSON:

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename="Chitanta-CH.1.pdf"
  • X-RateLimit-Limit: 120
  • X-RateLimit-Remaining: 119

Încasări - Șterge

DELETE /api/v6/invoices/{invoice_id}/receipts/{receipt_id}

Șterge încasarea și recalculează starea de încasare a documentului.

Răspuns: statusMessage Incasare stearsa, data: receipt_id și document (documentul actualizat).

Erori: 404 Incasarea nu a fost gasita; 400 Eroare stergere incasare: ... (încasări create automat din credit / stornare).

curl -X DELETE 'https://webill.ro/api/v6/invoices/1/receipts/1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Incasare stearsa",
  "data": {
    "receipt_id": 2,
    "document": {
      "id": 1,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 1,
      "number_display": "WB000001",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "partial",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 1,
            "sort_order": 1,
            "type": 1,
            "denumire": "Abonament platformă",
            "nota": "Luna curentă",
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 1000,
            "pret_fara_tva": 826.45,
            "valoare": 826.45,
            "tva": 173.55,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          },
          {
            "id": 2,
            "sort_order": 2,
            "type": 1,
            "denumire": "Licență utilizator suplimentar",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 2,
            "cota_tva": 21,
            "pret_cu_tva": 181.5,
            "pret_fara_tva": 150,
            "valoare": 300,
            "tva": 63,
            "discount": 36.3,
            "discount_net": 30,
            "discount_tva": 6.3,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 1096.45,
            "total_tva": 230.25
          }
        },
        "total": {
          "valoare": 1126.45,
          "tva": 236.55,
          "total": 1326.7
        },
        "discount": {
          "valoare": 30,
          "tva": 6.3,
          "total": 36.3
        },
        "stats": {
          "incasat": 100,
          "rest": 1226.7
        }
      },
      "items_count": 2,
      "payment_link_requested": false,
      "payment_link": null
    }
  }
}

Încasări - Alocare multiplă

POST /api/v6/invoices/receipts/bulk

O singură plată (ex. un OP din extras) împărțită pe mai multe facturi ale aceluiași client, de la cea mai veche: fiecare factură se achită integral înainte de următoarea; ultima poate rămâne parțial achitată. Se creează câte o încasare pe fiecare factură atinsă.

Body

Câmp Tip Obligatoriu Detalii
invoice_ids int[] da Facturile: același client, aceeași monedă, status emisa, cu rest de plată.
expected_balances obiect da {"<invoice_id>": <rest>} pentru fiecare factură: restul de plată pe care l-ai văzut (totals.stats.rest). Dacă între timp s-a schimbat, cererea e refuzată, ca să nu aloci pe date vechi.
amount număr > 0 da Suma totală; cel mult suma resturilor.
date AAAA-LL-ZZ da Data încasării.
type string da op, bf, cash, card sau ramburs.
identifier string da, în afară de cash Referința plății, aceeași pe toate încasările.
serie_id int la cash Seria cu chitanțier; fiecare factură primește chitanța ei.
notes string nu Observații.

Scriptul pre-request citește resturile celor două facturi (invoice_id, invoice_id_2), le pune în expected_balances și alege amount = restul primei facturi plus jumătate din restul celei de-a doua (prima se achită integral, a doua parțial).

Răspuns: statusMessage Incasare alocata, data.receipts[] (încasările create).

Erori — 422 Date invalide la incasare (câmpuri lipsă) sau 422 Eroare validare incasare: <motiv>:

  • Facturile selectate trebuie sa apartina aceluiasi client. / ... aceeasi moneda.
  • Doar pe facturile cu status Emisa se pot efectua incasari multiple. / Facturile selectate trebuie sa aiba rest de incasat.
  • Restul de incasat al unei facturi s-a schimbat intre timp. Reciteste facturile si incearca din nou. — expected_balances nu mai corespunde; recitește facturile.
  • Lipseste restul de incasat (expected_balances) pentru una dintre facturi. Reciteste facturile si incearca din nou. — lipsește o factură din expected_balances.
  • Valoarea incasarii nu poate depasi totalul facturilor selectate.
curl -X POST 'https://webill.ro/api/v6/invoices/receipts/bulk' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "invoice_ids": [1, 1],
  "expected_balances": {
    "1": 100,
    "1": 100
  },
  "type": "op",
  "identifier": "OP-2002",
  "amount": 100,
  "date": "2026-11-13",
  "notes": "Plata din extrasul de azi"
}'
{
  "status": 200,
  "statusMessage": "Incasare alocata",
  "data": {
    "receipts": [
      {
        "id": 4,
        "invoice_id": 1,
        "type": "op",
        "identifier": "OP-2002",
        "serie_id": null,
        "serie": null,
        "number": null,
        "receipt_number": "OP-2002",
        "date": "2026-10-29",
        "amount": 1226.7,
        "notes": "Plata din extrasul de azi",
        "created_at": "2026-10-29 12:53:48",
        "updated_at": "2026-10-29 12:53:48"
      },
      {
        "id": 5,
        "invoice_id": 2,
        "type": "op",
        "identifier": "OP-2002",
        "serie_id": null,
        "serie": null,
        "number": null,
        "receipt_number": "OP-2002",
        "date": "2026-10-29",
        "amount": 60.5,
        "notes": "Plata din extrasul de azi",
        "created_at": "2026-10-29 12:53:48",
        "updated_at": "2026-10-29 12:53:48"
      }
    ]
  }
}

Variante de stornare

GET /api/v6/invoices/{invoice_id}/storno

Ce se poate storna pe factură, înainte de POST .../storno.

Răspuns (data)

  • storno_allowed / storno_blocker — stornarea totală e posibilă / motivul pentru care nu e.
  • partial_storno_allowed / partial_storno_blocker — idem pentru stornarea parțială.
  • has_payments — factura are încasări (stornarea totală cere atunci payments_action).
  • default_date, default_serie_id — data și seria propuse.
  • reasons — motivele acceptate (cheie → text).
  • lines[] — liniile facturii: id (se trimite în lines[].id), description, um, qty, price, vat_rate, tax_included, qty_left / price_left / amount_left (ce a rămas de stornat), done (linie stornată complet). Listă goală când stornarea parțială nu e permisă.

Erori: 404 Factura nu a fost gasita.

curl 'https://webill.ro/api/v6/invoices/1/storno' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "invoice_id": 1,
    "number_display": "WB000001",
    "storno_allowed": true,
    "storno_blocker": null,
    "partial_storno_allowed": true,
    "partial_storno_blocker": null,
    "has_payments": true,
    "default_date": "2026-10-29",
    "default_serie_id": 1,
    "reasons": {
      "retur": "Retur marfă",
      "eroare": "Eroare de facturare",
      "anulare_comanda": "Anulare comandă",
      "serviciu_neprestat": "Serviciu neprestat",
      "altul": "Altul"
    },
    "lines": [
      {
        "id": 1,
        "description": "Abonament platformă",
        "um": "BUC",
        "negative": false,
        "qty": 1,
        "price": 1000,
        "vat_rate": 21,
        "tax_included": true,
        "discount_percent": null,
        "qty_left": 1,
        "price_left": 1000,
        "amount_left": 1000,
        "done": false
      },
      {
        "id": 2,
        "description": "Licență utilizator suplimentar",
        "um": "BUC",
        "negative": false,
        "qty": 2,
        "price": 150,
        "vat_rate": 21,
        "tax_included": false,
        "discount_percent": null,
        "qty_left": 2,
        "price_left": 150,
        "amount_left": 300,
        "done": false
      }
    ]
  }
}

Stornează parțial

POST /api/v6/invoices/{invoice_id}/storno

Stornare parțială: emite o factură storno doar pentru liniile / cantitățile alese (retur parțial, reducere de preț). Suma stornată trece în creditul clientului și se aplică pe restul de plată al facturii.

Body

Câmp Tip Obligatoriu Detalii
lines array (≤ 500) da, sau all Liniile de stornat: id (din Variante de stornare), mode, și qty sau price.
lines[].mode qty / price da qty: stornează qty bucăți. price: scade prețul unitar cu price pe cantitatea rămasă.
all bool nu true stornează tot ce a rămas. După o stornare parțială, este singurul mod de a storna restul.
date AAAA-LL-ZZ nu Data stornării; implicit azi, cel mai devreme data facturii.
serie_id int nu Seria facturii storno; implicit seria stornărilor din Preferințe, altfel seria facturii.
reason string nu retur, eroare, anulare_comanda, serviciu_neprestat, altul. Apare în observații și în e-Factura.
reason_note string ≤ 500 la altul Motivul, în text liber.

Răspuns: statusMessage Stornarea partiala a fost emisa, data: action (partial_storno), invoice (factura actualizată), storno_invoice (factura storno, cu totaluri negative).

Erori

  • 404 Factura nu a fost gasita.
  • 422 Eroare validare stornare: <motiv> + errors pe câmpuri, de ex. Alege cel putin o linie si cantitatea sau valoarea de stornat., Linia nu mai exista pe factura., Cantitatea de pe linia ... depaseste ce a ramas (N)., Stornarea nu poate fi datata inaintea facturii pe care o storneaza (...).
  • 409 — factura nu poate fi stornată parțial (motivul în statusMessage).
curl -X POST 'https://webill.ro/api/v6/invoices/1/storno' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "reason": "retur",
  "date": "2026-11-13",
  "lines": [
    {
      "id": 1,
      "mode": "qty",
      "qty": 1
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Stornarea partiala a fost emisa",
  "data": {
    "action": "partial_storno",
    "invoice": {
      "id": 1,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 1,
      "number_display": "WB000001",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "incasata",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 1,
            "sort_order": 1,
            "type": 1,
            "denumire": "Abonament platformă",
            "nota": "Luna curentă",
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 1000,
            "pret_fara_tva": 826.45,
            "valoare": 826.45,
            "tva": 173.55,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          },
          {
            "id": 2,
            "sort_order": 2,
            "type": 1,
            "denumire": "Licență utilizator suplimentar",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 2,
            "cota_tva": 21,
            "pret_cu_tva": 181.5,
            "pret_fara_tva": 150,
            "valoare": 300,
            "tva": 63,
            "discount": 36.3,
            "discount_net": 30,
            "discount_tva": 6.3,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 1096.45,
            "total_tva": 230.25
          }
        },
        "total": {
          "valoare": 1126.45,
          "tva": 236.55,
          "total": 1326.7
        },
        "discount": {
          "valoare": 30,
          "tva": 6.3,
          "total": 36.3
        },
        "stats": {
          "incasat": 1326.7,
          "rest": 0
        }
      },
      "items_count": 2,
      "payment_link_requested": false,
      "payment_link": null
    },
    "storno_invoice": {
      "id": 5,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 5,
      "number_display": "WB000005",
      "date": "2026-10-29",
      "due_days": 0,
      "due_date": "29.10.2026",
      "due_date_iso": "2026-10-29",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "compensata",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 6,
            "sort_order": 1,
            "type": -1,
            "denumire": "Abonament platformă",
            "nota": "Luna curentă",
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 1000,
            "pret_fara_tva": 826.45,
            "valoare": 826.45,
            "tva": 173.55,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": -826.45,
            "total_tva": -173.55
          }
        },
        "total": {
          "valoare": -826.45,
          "tva": -173.55,
          "total": -1000
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 0,
          "rest": -1000
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    }
  }
}

Stornează total

POST /api/v6/invoices/{invoice_id}/storno

Stornare totală: emite factura storno pentru întreaga factură (fără lines / all). Se folosește pentru facturile trimise în SPV; o factură netrimisă se poate și anula (Anulează).

Body (toate opționale): date, serie_id, reason, reason_note (ca la stornarea parțială) și:

Câmp Tip Obligatoriu Detalii
payments_action credit / refund dacă factura are încasări credit: suma încasată trece în creditul clientului (se poate folosi la încasări cu type: credit). refund: suma se restituie clientului.

Răspuns: statusMessage Factura a fost stornata, data: action (storno), invoice, storno_invoice (status storno).

Erori

  • 409 INVOICE_STORNO_HAS_PAYMENTS — factura are încasări și lipsește payments_action.
  • 409 INVOICE_STORNO_NOT_ALLOWED / 409 cu motivul (ex. Factura are stornari partiale; restul se storneaza cu "all"., Factura a fost deja stornata.).
  • 422 INVOICE_STORNO_PAYMENTS_ACTION_INVALID; 422 Eroare validare stornare: ....
curl -X POST 'https://webill.ro/api/v6/invoices/1/storno' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "reason": "eroare",
  "date": "2026-11-13",
  "payments_action": "credit"
}'
{
  "status": 200,
  "statusMessage": "Factura a fost stornata",
  "data": {
    "action": "storno",
    "invoice": {
      "id": 4,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 4,
      "number_display": "WB000004",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "stornata",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 5,
            "sort_order": 1,
            "type": 1,
            "denumire": "Produs achitat online",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 242,
            "pret_fara_tva": 200,
            "valoare": 200,
            "tva": 42,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 200,
            "total_tva": 42
          }
        },
        "total": {
          "valoare": 200,
          "tva": 42,
          "total": 242
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 242,
          "rest": 0
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    },
    "storno_invoice": {
      "id": 6,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 6,
      "number_display": "WB000006",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "storno",
      "status_incasare": "stornata",
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 7,
            "sort_order": 1,
            "type": -1,
            "denumire": "Produs achitat online",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 242,
            "pret_fara_tva": 200,
            "valoare": 200,
            "tva": 42,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": -200,
            "total_tva": -42
          }
        },
        "total": {
          "valoare": -200,
          "tva": -42,
          "total": -242
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 0,
          "rest": -242
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    }
  }
}

Anulează

POST /api/v6/invoices/{invoice_id}/cancel

Anulează factura sau, dacă a fost deja trimisă în SPV, o stornează (o factură trimisă în SPV nu se mai poate anula).

Situație Rezultat data.action
Netrimisă în SPV, fără încasări status anulata cancelled
Trimisă în SPV se emite factura storno (data.storno_invoice) storno
Deja anulată / stornată nimic (idempotent) already_cancelled / already_storno

Body (opțional): payments_action (credit / refund), folosit doar când se ajunge la stornare și factura are încasări.

Răspuns: data: action, invoice, storno_invoice (doar la stornare).

Erori

  • 404 Factura nu a fost gasita.
  • 409 INVOICE_CANCEL_HAS_PAYMENTS — factura are încasări: șterge-le sau stornează factura.
  • 409 INVOICE_CANCEL_NOT_ALLOWED; la stornare: 409 INVOICE_STORNO_HAS_PAYMENTS, INVOICE_STORNO_NOT_ALLOWED.
curl -X POST 'https://webill.ro/api/v6/invoices/1/cancel' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{}'
{
  "status": 200,
  "statusMessage": "Factura a fost anulata",
  "data": {
    "action": "cancelled",
    "invoice": {
      "id": 3,
      "document_type": "invoice",
      "company_id": 1,
      "serie_id": 1,
      "serie": "WB",
      "number": 3,
      "number_display": "WB000003",
      "date": "2026-10-29",
      "due_days": 15,
      "due_date": "13.11.2026",
      "due_date_iso": "2026-11-13",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "anulata",
      "status_incasare": null,
      "efactura_type": 380,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 4,
            "sort_order": 1,
            "type": 1,
            "denumire": "Abonament lunar",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 121,
            "pret_fara_tva": 100,
            "valoare": 100,
            "tva": 21,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 100,
            "total_tva": 21
          }
        },
        "total": {
          "valoare": 100,
          "tva": 21,
          "total": 121
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 0,
          "rest": 121
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    }
  }
}

Proforme

Facturi proforme: emitere, modificare, PDF, email și încasări (avansuri). Proforma se convertește în factură fiscală din WeBill; o proformă convertită nu mai acceptă modificări sau încasări. Proformele nu au anulare / stornare prin endpoint dedicat: anularea se face cu PATCH status: anulata.

Creează

POST /api/v6/proforme

Emite o proformă în seria aleasă (proforma_series din Nomenclatoare > Facturi). Câmpurile sunt cele ale facturii (fără order_id, curier, awb, generate_payment_link); document_type este întotdeauna 100.

Body

Câmp Tip Obligatoriu Detalii
client_id int unul din client_id / client Client existent al companiei (vezi Clienți).
client obiect unul din client_id / client Client inline, cu aceleași câmpuri și reguli ca POST /clients (persoana juridică existentă cu același CUI este refolosită). Eroare → 422 Client invalid: ....
items array da Cel puțin o linie (vezi mai jos).
serie_id int nu Seria (Nomenclatoare > Facturi: invoice_series / proforma_series). Implicit seria marcată „Implicită” în Setări, altfel prima serie activă. Serie străină / inactivă → 422 INVALID_INVOICE_SERIE / INVALID_PROFORMA_SERIE.
delegate_id int nu Delegatul (delegates). Implicit delegatul marcat „Implicit” în Setări, altfel primul delegat activ. → 422 INVALID_DELEGATE.
bank_accounts int[] nu Conturile bancare tipărite pe document (banks). Implicit contul marcat „Implicit” în moneda documentului, altfel toate conturile active. → 422 INVALID_BANK_ACCOUNT.
issue_date AAAA-LL-ZZ nu Data documentului; implicit azi. O factură nu poate fi datată înaintea ultimei facturi emise din aceeași serie (422).
due_days / due_date int ≥ 0 sau dată nu Termenul de plată: numărul de zile (implicit 15) sau direct data scadenței, AAAA-LL-ZZ (sau ZZ.LL.AAAA), care nu poate fi înaintea datei documentului.
currency string (3) nu Implicit RON. Lista în Nomenclatoare > Facturi (currencies).
exchange_rate număr nu Implicit cursul BNR al datei documentului (1 pentru RON).
language ro / en nu Limba documentului (PDF, email). Implicit ro.
comments string nu Observații tipărite pe document.

Linii (items[])

Câmp Tip Obligatoriu Detalii
description string ≤ 255 da* Denumirea produsului / serviciului.
details string nu Text suplimentar pe linie.
um string ≤ 50 da* Unitatea de măsură: denumirea folosită de companie (ex. BUC, ORA) sau codul UN/ECE (H87, HUR).
qty număr > 0 da Cantitatea. Zecimale cu punct sau virgulă.
unit_price număr ≥ 0 da* Prețul unitar, în moneda liniei.
tax_included bool nu Implicit true: prețul include TVA. false = preț fără TVA.
tax_value număr 0–100 nu Cota TVA în procente (ex. 21, 11, 0). Se potrivește cu o cotă activă a companiei cu exact acest procent; vezi taxes din Nomenclatoare > Facturi.
tax_id int nu ID-ul cotei TVA din Nomenclatoare > Facturi. Are prioritate față de tax_value. Cotă inexistentă / inactivă → 422 INVALID_TAX.
discount număr nu Reducere pe linie, ca valoare (în moneda liniei).
discount_type string nu Doar valoric (implicit). Reducerea procentuală nu este disponibilă prin API.
currency string (3) nu Moneda liniei; implicit moneda documentului. Conversia se face la cursul BNR al datei documentului.
product_id int nu Produs din Nomenclatoare > Produse și servicii: câmpurile netrimise (description, details, um, unit_price, currency, tax_id, tax_included, cpv_code) se completează din produs. Produs inexistent → 422 INVALID_PRODUCT.
cpv_code string nu Cod CPV (achiziții publice).

* nu sunt obligatorii când linia are product_id. O cantitate, un preț sau o reducere negativă marchează linia ca linie de stornare.

Răspuns: statusMessage Document creat, data.document_type = proforma.

data (document)

  • id, document_type (invoice / proforma), company_id, serie_id, serie, number, number_display (ex. WB000012).
  • date (AAAA-LL-ZZ), due_days, due_date (ZZ.LL.AAAA, păstrat așa pentru integrările existente), due_date_iso (aceeași zi, AAAA-LL-ZZ), currency, exchange_rate, language, efactura_type (380 / 751 / 389 / 100).
  • status: emisa, anulata, storno (factura inversă a unei stornări).
  • status_incasare: pending (neîncasată), partial, incasata, compensata (închisă din credit / stornare parțială), stornata.
  • client: obiectul client (ca la Clienți > Detaliu).
  • totals.items[]: liniile — id (folosit la stornare), denumire, nota, um, um_code, qty, cota_tva, pret_cu_tva, pret_fara_tva, valoare (fără TVA), tva, discount, discount_net, discount_tva, cpv_code.
  • totals.subtotal: pe cota TVA ("21": {"total_fara_tva", "total_tva"}); totals.total: valoare (fără TVA) și tva sunt înainte de reduceri, total (de plată) este după reduceri: total = valoare + tva - discount.total; totals.discount: reducerile; totals.stats: incasat, rest (rest de plată).
  • items_count, payment_link_requested, payment_link (linkul de plată Netopia activ sau null).

Erori

  • 400 Payload JSON invalid: ... — corpul nu este JSON valid.
  • 422 Date invalide la linii, cu erorile în errors pe cheia liniei (ex. {"items.0.description": ["Campul description este obligatoriu."]}); la fel pentru items: [].
  • 422 Data din campul issue_date nu este valida (format AAAA-LL-ZZ). (sau date, după câmpul trimis) — o dată pe care serverul nu o poate citi nu mai devine data de azi.
  • 422 pentru un due_date care nu e nici număr de zile, nici dată, sau care e înaintea datei documentului.
  • 422 Clientul nu a fost identificat — lipsește client_id / client sau clientul nu este al companiei.
  • 422 Date invalide la document + errors pe câmpuri (ex. errors.items).
  • 422 cu errors.code: INVALID_INVOICE_SERIE, INVALID_PROFORMA_SERIE, INVALID_DELEGATE, INVALID_BANK_ACCOUNT, INVALID_TAX, INVALID_TAX_CLIENT (cotă de taxare inversă / intracomunitară nepotrivită clientului), INVALID_PRODUCT, INVALID_CLIENT, INVALID_ITEMS.
  • 422 Data facturii (...) nu poate fi inaintea ultimei facturi emise din seria ... (errors.issue_date).
curl -X POST 'https://webill.ro/api/v6/proforme' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client_id": 1,
  "serie_id": 1,
  "delegate_id": 1,
  "bank_accounts": [
    1
  ],
  "issue_date": "2026-11-13",
  "due_days": 7,
  "currency": "RON",
  "language": "ro",
  "comments": "Oferta valabila 7 zile",
  "items": [
    {
      "description": "Implementare magazin online",
      "um": "BUC",
      "qty": 1,
      "unit_price": 5000,
      "tax_included": false,
      "tax_value": 21
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Document creat",
  "data": {
    "id": 7,
    "document_type": "proforma",
    "company_id": 1,
    "serie_id": 1,
    "serie": "PF",
    "number": 1,
    "number_display": "PF000001",
    "date": "2026-10-29",
    "due_days": 7,
    "due_date": "05.11.2026",
    "due_date_iso": "2026-11-05",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 100,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 8,
          "sort_order": 1,
          "type": 1,
          "denumire": "Implementare magazin online",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 6050,
          "pret_fara_tva": 5000,
          "valoare": 5000,
          "tva": 1050,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 5000,
          "total_tva": 1050
        }
      },
      "total": {
        "valoare": 5000,
        "tva": 1050,
        "total": 6050
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 6050
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Actualizează

PATCH /api/v6/proforme/{proforma_id}

Modifică proforma; doar câmpurile trimise se schimbă. Ca la facturi, fără client_id (sau client) proforma își păstrează clientul, iar items înlocuiește toate liniile. status: emisa sau anulata.

Răspuns: statusMessage Document actualizat.

Erori: 404 Documentul nu a fost gasit; 422 Clientul nu a fost identificat; celelalte de la Creează.

curl -X PATCH 'https://webill.ro/api/v6/proforme/1' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "client_id": 1,
  "due_days": 10,
  "comments": "Oferta prelungita",
  "items": [
    {
      "description": "Implementare magazin online",
      "um": "BUC",
      "qty": 1,
      "unit_price": 4500,
      "tax_included": false,
      "tax_value": 21
    }
  ]
}'
{
  "status": 200,
  "statusMessage": "Document actualizat",
  "data": {
    "id": 7,
    "document_type": "proforma",
    "company_id": 1,
    "serie_id": 1,
    "serie": "PF",
    "number": 1,
    "number_display": "PF000001",
    "date": "2026-10-29",
    "due_days": 10,
    "due_date": "08.11.2026",
    "due_date_iso": "2026-11-08",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 100,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 9,
          "sort_order": 1,
          "type": 1,
          "denumire": "Implementare magazin online",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 5445,
          "pret_fara_tva": 4500,
          "valoare": 4500,
          "tva": 945,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 4500,
          "total_tva": 945
        }
      },
      "total": {
        "valoare": 4500,
        "tva": 945,
        "total": 5445
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 5445
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Detaliu

GET /api/v6/proforme/{proforma_id}

Proforma, cu clientul, totalurile și situația încasării.

data (document)

  • id, document_type (invoice / proforma), company_id, serie_id, serie, number, number_display (ex. WB000012).
  • date (AAAA-LL-ZZ), due_days, due_date (ZZ.LL.AAAA, păstrat așa pentru integrările existente), due_date_iso (aceeași zi, AAAA-LL-ZZ), currency, exchange_rate, language, efactura_type (380 / 751 / 389 / 100).
  • status: emisa, anulata, storno (factura inversă a unei stornări).
  • status_incasare: pending (neîncasată), partial, incasata, compensata (închisă din credit / stornare parțială), stornata.
  • client: obiectul client (ca la Clienți > Detaliu).
  • totals.items[]: liniile — id (folosit la stornare), denumire, nota, um, um_code, qty, cota_tva, pret_cu_tva, pret_fara_tva, valoare (fără TVA), tva, discount, discount_net, discount_tva, cpv_code.
  • totals.subtotal: pe cota TVA ("21": {"total_fara_tva", "total_tva"}); totals.total: valoare (fără TVA) și tva sunt înainte de reduceri, total (de plată) este după reduceri: total = valoare + tva - discount.total; totals.discount: reducerile; totals.stats: incasat, rest (rest de plată).
  • items_count, payment_link_requested, payment_link (linkul de plată Netopia activ sau null).

Erori: 404 Proforma nu a fost gasita.

curl 'https://webill.ro/api/v6/proforme/1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "id": 7,
    "document_type": "proforma",
    "company_id": 1,
    "serie_id": 1,
    "serie": "PF",
    "number": 1,
    "number_display": "PF000001",
    "date": "2026-10-29",
    "due_days": 10,
    "due_date": "08.11.2026",
    "due_date_iso": "2026-11-08",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 100,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 9,
          "sort_order": 1,
          "type": 1,
          "denumire": "Implementare magazin online",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 5445,
          "pret_fara_tva": 4500,
          "valoare": 4500,
          "tva": 945,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 4500,
          "total_tva": 945
        }
      },
      "total": {
        "valoare": 4500,
        "tva": 945,
        "total": 5445
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 5445
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Caută după serie și număr

GET /api/v6/proforme/find

Proforma cu seria și numărul date, confirmată de codul fiscal al emitentului și, opțional, de dată și de client, în compania tokenului: același răspuns ca la Detaliu (GET /proforme/{id}). Util când sistemul tău a păstrat numărul tipărit, nu ID-ul WeBill.

Exact sau nimic. Căutarea nu ghicește: dacă ceva nu corespunde întocmai sau mai multe documente se potrivesc, primești o eroare, niciodată documentul „cel mai probabil”. O automatizare care acționează pe răspuns (încasare, stornare) nu poate atinge astfel o factură greșită.

Query (serie, number și company_vat obligatorii; restul opționale, fiecare trimis se compară)

Parametru Detalii
serie Seria, ex. WB.
number Numărul: doar cifre (12, 0012) sau numărul tipărit cu seria în față (WB0012). Orice altceva (12a, WB-12, altă serie) → 400.
company_vat CUI-ul emitentului, cum apare pe document (pentru un punct de lucru, al companiei-mamă). Se acceptă cu sau fără RO, cu spații.
date Opțional. Data documentului, AAAA-LL-ZZ. Deosebește documentele vechi cu aceeași serie și același număr.
client_vat Opțional. CUI-ul / CNP-ul clientului cum a fost tipărit la emitere (o schimbare ulterioară a clientului nu contează). Cu sau fără RO; un cod străin își păstrează prefixul țării (DE123...). La persoanele fizice fără CNP (0000000000000) codul nu identifică pe nimeni: lasă-l gol sau folosește date.
client_name Opțional. Numele clientului de pe document, comparat fără majuscule, diacritice și spații în plus.
Răspuns errors.code Când
200 — Exact un document se potrivește.
400 — Lipsește un parametru obligatoriu, number nu este exact numărul documentului sau date nu e o dată AAAA-LL-ZZ.
404 DOCUMENT_NOT_FOUND Nu există niciun document cu seria și numărul acestea (Proforma nu a fost gasita).
404 COMPANY_MISMATCH Documentul există, dar emitentul are alt cod fiscal (ex. tokenul altei companii).
404 DATE_MISMATCH Documentul există, dar are altă dată.
404 CLIENT_MISMATCH Documentul există, dar clientul are alt cod fiscal sau alt nume.
409 AMBIGUOUS_DOCUMENT Mai multe documente se potrivesc (aceeași serie și același număr, fără date sau client care să le deosebească) (ex. o factură veche și stornarea ei cu același număr). errors.candidates[] are id, date, status: alege documentul și cere-l cu GET /proforme/{id}.

Facturile fiscale nu sunt căutate aici (au invoices/find). Ciornele nu au număr, deci nu se găsesc.

curl 'https://webill.ro/api/v6/proforme/find?serie=WB&number=1&company_vat=10000008&client_vat=10000008' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "success",
  "data": {
    "id": 7,
    "document_type": "proforma",
    "company_id": 1,
    "serie_id": 1,
    "serie": "PF",
    "number": 1,
    "number_display": "PF000001",
    "date": "2026-10-29",
    "due_days": 10,
    "due_date": "08.11.2026",
    "due_date_iso": "2026-11-08",
    "currency": "RON",
    "exchange_rate": 1,
    "status": "emisa",
    "status_incasare": "pending",
    "efactura_type": 100,
    "language": "ro",
    "client": {
      "id": 2,
      "company": "EXEMPLU DISTRIBUTIE SRL",
      "is_pf": false,
      "has_vat": true,
      "vat": "10000008",
      "country": {
        "code": "RO",
        "name": "Romania"
      },
      "state": {
        "code": "B",
        "name": "Bucuresti"
      },
      "city": "Sector 1",
      "email": "[email protected]",
      "address_1": "Str. Exemplu nr. 3",
      "phone": "0722999999",
      "bank": "Banca Exemplu",
      "iban": "RO49AAAA1B31007593840000"
    },
    "totals": {
      "items": [
        {
          "id": 9,
          "sort_order": 1,
          "type": 1,
          "denumire": "Implementare magazin online",
          "nota": null,
          "cpv_code": null,
          "um": "BUC",
          "um_code": "H87",
          "qty": 1,
          "cota_tva": 21,
          "pret_cu_tva": 5445,
          "pret_fara_tva": 4500,
          "valoare": 4500,
          "tva": 945,
          "discount": 0,
          "discount_net": 0,
          "discount_tva": 0,
          "discount_percent": null
        }
      ],
      "subtotal": {
        "21": {
          "total_fara_tva": 4500,
          "total_tva": 945
        }
      },
      "total": {
        "valoare": 4500,
        "tva": 945,
        "total": 5445
      },
      "discount": {
        "valoare": 0,
        "tva": 0,
        "total": 0
      },
      "stats": {
        "incasat": 0,
        "rest": 5445
      }
    },
    "items_count": 1,
    "payment_link_requested": false,
    "payment_link": null
  }
}

Descarcă PDF

GET /api/v6/proforme/{proforma_id}/download

PDF-ul documentului. Răspunsul este fișierul (Content-Type: application/pdf, Content-Disposition: attachment; filename=proforma-pf000003-09-10-2026.pdf).

Erori (JSON): 404 Documentul nu a fost gasit.

curl 'https://webill.ro/api/v6/proforme/1/download' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -o document.pdf

Răspunsul este fișierul, nu JSON:

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename=proforma-pf000001-29-10-2026.pdf
  • X-RateLimit-Limit: 120
  • X-RateLimit-Remaining: 119

Trimite pe email

POST /api/v6/proforme/{proforma_id}/email

Trimite documentul pe email, cu PDF-ul atașat. Trimiterea se face asincron (în coadă), deci răspunsul confirmă programarea, nu livrarea. Fiecare trimitere apare în istoricul de emailuri al documentului din WeBill (sursa API), la facturi și la proforme.

Body (toate opționale)

Câmp Tip Obligatoriu Detalii
to string nu Destinatarul. Implicit emailul clientului (prima adresă validă; celelalte trec în CC).
cc string nu Adrese în copie, separate prin , sau ;.
subject string nu Subiectul. Implicit Factura fiscala #WB000012 / Factura proforma #PF000003.

Răspuns: statusMessage Email programat pentru trimitere, data: document_id, recipient.

Erori: 404 Documentul nu a fost gasit; 400 Clientul nu are email setat (fără to și fără email la client).

curl -X POST 'https://webill.ro/api/v6/proforme/1/email' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "to": "[email protected]",
  "subject": "Oferta pentru implementarea magazinului online"
}'
{
  "status": 200,
  "statusMessage": "Email programat pentru trimitere",
  "data": {
    "document_id": 7,
    "recipient": "[email protected]"
  }
}

Încasări - Listă

GET /api/v6/proforme/{proforma_id}/receipts

Încasările documentului, ordonate după dată, plus documentul (cu totals.stats.incasat / rest).

Răspuns: statusMessage Incasari document, data: document, receipts[].

data (încasare): id, invoice_id (ID-ul documentului), type, identifier, serie_id, serie, number, receipt_number (ex. CH.1, doar la numerar), date, amount, notes, created_at, updated_at.

curl 'https://webill.ro/api/v6/proforme/1/receipts' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Incasari document",
  "data": {
    "document": {
      "id": 7,
      "document_type": "proforma",
      "company_id": 1,
      "serie_id": 1,
      "serie": "PF",
      "number": 1,
      "number_display": "PF000001",
      "date": "2026-10-29",
      "due_days": 10,
      "due_date": "08.11.2026",
      "due_date_iso": "2026-11-08",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "pending",
      "efactura_type": 100,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 9,
            "sort_order": 1,
            "type": 1,
            "denumire": "Implementare magazin online",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 5445,
            "pret_fara_tva": 4500,
            "valoare": 4500,
            "tva": 945,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 4500,
            "total_tva": 945
          }
        },
        "total": {
          "valoare": 4500,
          "tva": 945,
          "total": 5445
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 0,
          "rest": 5445
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    },
    "receipts": []
  }
}

Încasări - Creează

POST /api/v6/proforme/{proforma_id}/receipts

Înregistrează o încasare pe document. Starea de încasare a documentului (status_incasare) se actualizează: pending → partial → incasata. O sumă mai mare decât restul este acceptată; diferența intră în creditul clientului.

Body

Câmp Tip Obligatoriu Detalii
type string da Tipul încasării (tabelul de mai jos).
amount număr > 0 da Suma, în moneda documentului.
date AAAA-LL-ZZ da Data încasării.
identifier string ≤ 255 la op / bf / card / ramburs Referința plății (nr. OP, ID tranzacție, AWB, nr. bon).
serie_id int la cash Seria cu chitanțier (invoice_series[].id din Nomenclatoare > Facturi). Chitanța se numerotează automat.
notes string nu Observații.
type Ce este Câmpuri cerute în plus
op Ordin de plată / transfer bancar identifier (ex. numărul OP)
bf Bon fiscal identifier (numărul bonului)
card Plată cu cardul / POS / online identifier (ex. ID-ul tranzacției)
ramburs Ramburs prin curier identifier (ex. AWB)
cash Numerar, cu chitanță numerotată automat serie_id = ID-ul seriei de facturi care are chitanțierul (invoice_series[].id, câmpul receipt_serie)
avans Avans —
credit Din creditul clientului (sume plătite în plus, stornări) — ; suma nu poate depăși creditul disponibil

Răspuns: statusMessage Incasare creata.

data (încasare): id, invoice_id (ID-ul documentului), type, identifier, serie_id, serie, number, receipt_number (ex. CH.1, doar la numerar), date, amount, notes, created_at, updated_at.

Erori

  • 404 Documentul nu a fost gasit.
  • 422 Date invalide la incasare + errors pe câmpuri (ex. identifier, serie_id).
  • 422 INVOICE_PAYMENT_AMOUNT_INVALID, INVOICE_PAYMENT_TYPE_INVALID, INVALID_RECEIPT_SERIE.
  • 422 Creditul disponibil al clientului este ... RON. (tipul credit).
  • 409 INVOICE_PAYMENT_NOT_ALLOWED — documentul nu mai acceptă încasări (anulat, stornat, proformă convertită).

Încasările proformei se preiau pe factura în care este convertită.

curl -X POST 'https://webill.ro/api/v6/proforme/1/receipts' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "type": "op",
  "identifier": "OP-3003",
  "amount": 1000,
  "date": "2026-11-13",
  "notes": "Avans 20%"
}'
{
  "status": 200,
  "statusMessage": "Incasare creata",
  "data": {
    "id": 6,
    "invoice_id": 7,
    "type": "op",
    "identifier": "OP-3003",
    "serie_id": null,
    "serie": null,
    "number": null,
    "receipt_number": "OP-3003",
    "date": "2026-10-29",
    "amount": 1000,
    "notes": "Avans 20%",
    "created_at": "2026-10-29 12:53:49",
    "updated_at": "2026-10-29 12:53:49"
  }
}

Încasări - Actualizează

PATCH /api/v6/proforme/{proforma_id}/receipts/{proforma_receipt_id}

Modifică doar câmpurile trimise: amount, date, identifier, notes. Tipul și seria încasării nu se pot schimba (422 Tipul incasarii nu poate fi modificat.): pentru alt tip, șterge încasarea și creeaz-o din nou.

Răspuns: statusMessage Incasare actualizata, data = încasarea.

Erori: 404 Incasarea nu a fost gasita; 422 Date invalide la incasare; 422 Eroare validare incasare: ... (sumă ≤ 0, încasare creată automat din credit / stornare, factură stornată).

curl -X PATCH 'https://webill.ro/api/v6/proforme/1/receipts/1' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -d '{
  "amount": 1500,
  "notes": "Avans 30%"
}'
{
  "status": 200,
  "statusMessage": "Incasare actualizata",
  "data": {
    "id": 6,
    "invoice_id": 7,
    "type": "op",
    "identifier": "OP-3003",
    "serie_id": null,
    "serie": null,
    "number": null,
    "receipt_number": "OP-3003",
    "date": "2026-10-29",
    "amount": 1500,
    "notes": "Avans 30%",
    "created_at": "2026-10-29 12:53:49",
    "updated_at": "2026-10-29 12:53:49"
  }
}

Încasări - Descarcă chitanță

GET /api/v6/proforme/{proforma_id}/receipts/{proforma_receipt_id}/download

PDF-ul chitanței (încasări cash) sau al dovezii de încasare. Răspunsul este fișierul (Content-Type: application/pdf, Content-Disposition: attachment; filename="Chitanta-CH.1.pdf").

Erori (JSON): 404 Documentul nu a fost gasit / Incasarea nu a fost gasita.

curl 'https://webill.ro/api/v6/proforme/1/receipts/1/download' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU' \
  -o document.pdf

Răspunsul este fișierul, nu JSON:

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename="Chitanta-OP-3003.pdf"
  • X-RateLimit-Limit: 120
  • X-RateLimit-Remaining: 119

Încasări - Șterge

DELETE /api/v6/proforme/{proforma_id}/receipts/{proforma_receipt_id}

Șterge încasarea și recalculează starea de încasare a documentului.

Răspuns: statusMessage Incasare stearsa, data: receipt_id și document (documentul actualizat).

Erori: 404 Incasarea nu a fost gasita; 400 Eroare stergere incasare: ... (încasări create automat din credit / stornare).

curl -X DELETE 'https://webill.ro/api/v6/proforme/1/receipts/1' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer TOKENUL_TAU'
{
  "status": 200,
  "statusMessage": "Incasare stearsa",
  "data": {
    "receipt_id": 6,
    "document": {
      "id": 7,
      "document_type": "proforma",
      "company_id": 1,
      "serie_id": 1,
      "serie": "PF",
      "number": 1,
      "number_display": "PF000001",
      "date": "2026-10-29",
      "due_days": 10,
      "due_date": "08.11.2026",
      "due_date_iso": "2026-11-08",
      "currency": "RON",
      "exchange_rate": 1,
      "status": "emisa",
      "status_incasare": "pending",
      "efactura_type": 100,
      "language": "ro",
      "client": {
        "id": 2,
        "company": "EXEMPLU DISTRIBUTIE SRL",
        "is_pf": false,
        "has_vat": true,
        "vat": "10000008",
        "country": {
          "code": "RO",
          "name": "Romania"
        },
        "state": {
          "code": "B",
          "name": "Bucuresti"
        },
        "city": "Sector 1",
        "email": "[email protected]",
        "address_1": "Str. Exemplu nr. 3",
        "phone": "0722999999",
        "bank": "Banca Exemplu",
        "iban": "RO49AAAA1B31007593840000"
      },
      "totals": {
        "items": [
          {
            "id": 9,
            "sort_order": 1,
            "type": 1,
            "denumire": "Implementare magazin online",
            "nota": null,
            "cpv_code": null,
            "um": "BUC",
            "um_code": "H87",
            "qty": 1,
            "cota_tva": 21,
            "pret_cu_tva": 5445,
            "pret_fara_tva": 4500,
            "valoare": 4500,
            "tva": 945,
            "discount": 0,
            "discount_net": 0,
            "discount_tva": 0,
            "discount_percent": null
          }
        ],
        "subtotal": {
          "21": {
            "total_fara_tva": 4500,
            "total_tva": 945
          }
        },
        "total": {
          "valoare": 4500,
          "tva": 945,
          "total": 5445
        },
        "discount": {
          "valoare": 0,
          "tva": 0,
          "total": 0
        },
        "stats": {
          "incasat": 0,
          "rest": 5445
        }
      },
      "items_count": 1,
      "payment_link_requested": false,
      "payment_link": null
    }
  }
}