Cuprins
Un tabel cu cifra de afaceri pe cinci ani e corect și aproape nimeni nu-l citește. Un grafic îți arată într-o secundă dacă firma crește, stă pe loc sau scade și dacă profitul ține pasul cu vânzările. Mai jos e un script de vreo 50 de rânduri care face exact graficul ăsta din bilanțurile publice.
Îți trebuie Python 3, bibliotecile requests și matplotlib și cam un sfert de oră. Prima rulare o faci în sandbox, unde cererile nu consumă credite. Sandbox-ul cere totuși o cheie API, deci un cont; contul e gratuit și nu cere card.
Instalarea
pip install requests matplotlib
Sandbox-ul BilantAPI.ro răspunde la https://www.bilantapi.ro/api/sandbox/v1 cu date fictive, pe CUI-uri de test precum 90000010. Răspunsurile au aceeași formă ca în producție, deci codul scris acum merge neschimbat și pe date reale. Autentificarea e cu aceeași cheie, în antetul X-API-KEY sau ca Bearer token.
Ce rută alegi
Pentru date pe mai mulți ani, API-ul Bilanț are trei variante:
| Rută | Ce primești | Cost |
|---|---|---|
/bilant/{cui}/{an} | Un singur an | 1 credit pe an |
/bilant/{cui} | Toți anii, cu datele, indicatorii și evoluția | 1 credit |
/bilant/{cui}/evolutie | Serie multi-an, cu creșteri anuale și CAGR | 2 credite |
Scriptul de mai jos cere fiecare an separat, pentru că așa codul se urmărește mai ușor. Pe un an, cifrele din formular vin în data.date (cifra_afaceri, angajati și celelalte), iar indicatorii în data.indicatori, unde e și rezultatul cu semn, rezultat_net. În producție, pe multe firme, eu aș trece pe ruta completă, care costă un singur credit pentru toți anii. Anii vin atunci în data.ani, cu aceeași formă. Detaliile sunt în documentație.

Citirea datelor
import requests
BAZA = "https://www.bilantapi.ro/api/sandbox/v1"
ANTETE = {"X-API-KEY": "cheia-ta"}
def an_bilant(cui, an):
r = requests.get(f"{BAZA}/bilant/{cui}/{an}", headers=ANTETE, timeout=20)
if r.status_code != 200:
return None
d = r.json()["data"]
cifre = d["date"]
return {
"an": an,
"ca": cifre.get("cifra_afaceri") or 0,
"rezultat": d["indicatori"]["rezultat_net"] or 0,
"angajati": cifre.get("angajati") or 0,
}
def serie(cui, ani):
date = [an_bilant(cui, an) for an in ani]
return [x for x in date if x is not None]
Rezultatul net îl iau din indicatori.rezultat_net, unde e deja calculat ca profit minus pierdere. Bilanțul are fie profit, fie pierdere, așa că profit_net singur ar arăta 0 într-un an pe pierdere, iar graficul ar minți frumos. Anii fără bilanț depus sunt săriți. O cerere fără rezultat nu consumă credite, deci nu plătești pentru anii lipsă.
Graficul
Cifra de afaceri și rezultatul stau pe aceeași axă, în milioane de lei. Angajații au cu totul altă scară, așa că merg pe o axă secundară, în dreapta.
import matplotlib.pyplot as plt
def deseneaza(cui, ani):
s = serie(cui, ani)
if len(s) < 2:
print("Prea puțini ani cu bilanț pentru un grafic.")
return
x = [p["an"] for p in s]
ca = [p["ca"] / 1e6 for p in s]
rez = [p["rezultat"] / 1e6 for p in s]
ang = [p["angajati"] for p in s]
fig, ax = plt.subplots(figsize=(9, 5))
ax.bar(x, ca, color="#9bb7d4", label="Cifra de afaceri (mil. lei)")
ax.plot(x, rez, color="#1f4e79", marker="o", label="Rezultat net (mil. lei)")
ax.axhline(0, color="grey", linewidth=0.8)
ax.set_xticks(x)
ax2 = ax.twinx()
ax2.plot(x, ang, color="#c55a11", linestyle="--", marker="s", label="Angajați")
linii = ax.get_legend_handles_labels()
linii2 = ax2.get_legend_handles_labels()
ax.legend(linii[0] + linii2[0], linii[1] + linii2[1], loc="upper left")
ax.set_title(f"Evoluția firmei {cui}")
fig.tight_layout()
fig.savefig(f"evolutie-{cui}.png", dpi=150)
deseneaza("90000010", range(2019, 2024))
După rulare ai un fișier evolutie-90000010.png cu datele fictive din sandbox. Linia orizontală de la zero e acolo intenționat: fără ea, un an pe pierdere se pierde printre celelalte puncte.
Pe date reale
Trecerea e scurtă. Verifică întâi că ai credite, pentru că în producție fiecare răspuns cu date se taxează. Schimbă BAZA în https://www.bilantapi.ro/api/v1, pune CUI-ul firmei care te interesează în locul celui de test și mută cheia într-o variabilă de mediu, nu în cod.
Cinci ani ceruți separat costă 5 credite pe firmă. Cu ruta completă, 1 credit. Pe zece firme diferența e mică, pe o mie deja contează.

Cum citești ce iese
Dacă barele cresc și linia rezultatului coboară, firma vinde mai mult și câștigă mai puțin. Fie luptă pe preț, fie costurile îi cresc mai repede decât vânzările. Dacă barele stau pe loc și angajații cresc, productivitatea scade, și merită să afli dacă firma se pregătește de o creștere sau doar își încarcă structura.
O linie a rezultatului sub zero mai mulți ani la rând înseamnă pierderi care mănâncă din capitalurile proprii; verifică și câmpul capitaluri. Iar un singur an foarte bun, izolat, poate fi un contract mare sau o vânzare de active. Nu-l extrapola.
Unde se greșește
Cea mai gravă greșeală e cheia API în browser. Dacă vrei graficul într-o pagină web, cere datele de pe server și trimite spre browser doar cifrele. O cheie pusă în JavaScript-ul paginii poate fi copiată de oricine o deschide.
Apoi, axa. La bare, pornește axa mereu de la zero, altfel o creștere de 5% arată ca o dublare. Primul an incomplet e altă capcană: o firmă înființată în cursul anului are în primul bilanț doar câteva luni, așa că marchează-l sau lasă-l deoparte, ca să nu pară că firma a explodat în anul doi.
Și nu cere aceleași date în fiecare zi. Dacă regenerezi graficul zilnic, citește din cache. Bilanțul unui an încheiat nu se schimbă, iar fiecare cerere nouă consumă credite.
Ce mai poți adăuga
Ruta /bilant/{cui}/evolutie întoarce rata medie anuală de creștere a cifrei de afaceri, în evolutie.cagr_ca, plus creșterile de la an la an pentru cifra de afaceri, rezultat și angajați. Pune cagr_ca în titlul graficului și ai rezumatul într-o singură cifră.
Pentru comparații cu concurența, desenează doar cifra de afaceri a trei-patru firme, ca linii. Mai multe devin greu de citit. Pentru până la 10 firme puse una lângă alta, API-ul Statistici are ruta /statistici/comparatie?cui=…, cu CUI-urile despărțite prin virgulă și, opțional, anul în an.
Imaginea salvată o pui direct într-un raport intern, într-o prezentare sau în fișa unui client. Dacă generezi rapoarte periodic, păstrează răspunsurile JSON într-o bază locală; bilanțurile depuse nu se schimbă, deci n-are rost să le ceri de două ori.
Toate rutele sunt pe pagina API-ului Bilanț. Cu cele 250 de credite gratuite de la înregistrare, fără card, desenezi evoluția pe toți anii pentru 250 de firme, dacă folosești ruta completă.
Întrebări frecvente
Pot rula scriptul fără să consum credite?
Da. Sandbox-ul de la https://www.bilantapi.ro/api/sandbox/v1 răspunde cu date fictive pe CUI-ul de test 90000010 și nu consumă credite. Îți trebuie totuși o cheie API, deci un cont gratuit, fără card.
Cât mă costă evoluția pe 5 ani a unei firme?
Cinci cereri pe ruta anuală costă 5 credite. Ruta completă /bilant/{cui}, cu toți anii, costă 1 credit.
Ce se întâmplă dacă firma n-are bilanț într-un an?
Scriptul sare anul respectiv, iar cererea fără rezultat nu consumă credite.



