API pentru dezvoltatori
Dacă trimiți acte în volum — casă de avocatură, bancă, firmă de recuperare, furnizor de utilități — nu are sens să treci prin formular de fiecare dată. API-ul face aceleași două lucruri pe care le face site-ul. Licitație: descrii lucrarea, iar birourile competente pentru adresele tale trimit prețul lor; alegi o ofertă și abia atunci se mișcă banii. Comandă directă: dacă știi deja cu ce birou vrei să lucrezi, îl numești și plătești pe loc. În ambele cazuri plata iese din creditul contului și primești răspunsul în JSON.
Cum începi
1. Cont de portal
Ai nevoie de un cont pe portalul clienților. Îl deschizi în câteva secunde, cu e-mailul firmei — același cont din care vezi comenzile și alimentezi creditul.
2. Token
În portal, la secțiunea API, generezi singur un token de forma exec_live_…, afișat o singură dată. În baza noastră stă doar amprenta lui: dacă îl pierzi, îl revoci și generezi altul.
3. Credit
Alimentezi contul din portal, cu factură. Fiecare comandă plasată prin API se scade din sold în momentul plasării, deci integrarea ta nu are de gestionat plăți per comandă.
Autentificare
Toate cererile merg pe HTTPS și poartă tokenul într-un antet. Nu există chei în query string: un URL ajunge în logurile serverului, în istoricul browserului și în antetul Referer, iar un token ajuns acolo trebuie considerat compromis.
curl https://executat.ro/api/v1/cont \
-H "Authorization: Bearer exec_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Dacă librăria ta face antetul Authorization incomod, acceptăm și X-API-Key cu aceeași valoare.
Drepturi
Un token are citire, comenzi sau ambele. Sunt intenționat grosiere: cineva vrea fie „citește ce am”, fie „cheltuie din soldul meu”. Dacă scriptul tău doar raportează, cere un token numai de citire — nu poate plasa comenzi nici dacă se rătăcește.
Medii
Prefixul spune ce este: exec_live_ lucrează pe comenzi reale și pe credit real, exec_test_ este pentru integrare. Verifică prefixul înainte de a porni pe producție — cele două arată la fel în restul lungimii.
Fluxul direct
Doi pași, și separarea este intenționată. Ofertarea nu scrie și nu debitează nimic, deci o poți apela oricât cât timp decizi; plasarea comenzii este locul unde se mișcă banii.
Folosește-l când ai deja un birou preferat sau când vrei un preț ferm imediat. Dacă nu ai, licitația dă de regulă un preț mai bun: pentru majoritatea birourilor tariful pe care îl vezi aici este plafonul legal, nu o ofertă a biroului.
1. Cere oferte
Competența teritorială este jumătatea grea a întrebării: un executor judecătoresc nu poate instrumenta oriunde. Trimite procedura și adresele, primești birourile care pot comunica legal actul acolo, cu prețul total al fiecăruia.
curl -X POST https://executat.ro/api/v1/oferte \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"serviciu": "somatie-de-plata",
"adrese": [
{ "lat": 44.4268, "lng": 26.1025, "eticheta": "Calea Victoriei 1, București", "detalii": "ap. 12" },
{ "text": "Strada Memorandumului 28, Cluj-Napoca" }
]
}'{
"serviciu": { "slug": "somatie-de-plata", "nume": "Notificare / somație", … },
"adrese": [ { "eticheta": "…", "lat": 44.4268, "judet": "București", … } ],
"total": 37,
"creditDisponibilBani": 100000,
"oferte": [
{
"executor": { "slug": "bej-exemplu", "birou": "BEJ Exemplu", "judet": "București", … },
"sursaPret": "tarif",
"onorariiBani": 24000,
"deplasareBani": 5000,
"subtotalBani": 29000,
"tvaProcent": 21,
"tvaBani": 6090,
"totalBani": 35090,
"acoperitDinCredit": true,
"completa": true,
"estimativ": false,
"linii": [ … ]
}
]
}2. Plasează comanda
Iei executor.slug din oferta aleasă și îl trimiți înapoi. Prețul se recalculează aici — dacă trimiți un total, este ignorat. O sumă venită din cererea clientului este o sumă pe care clientul o controlează, iar aceasta ajunge pe o factură. Tu alegi care birou; cât costă biroul spunem noi.
curl -X POST https://executat.ro/api/v1/comenzi \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: dosar-4471-notificare-1" \
-d '{
"serviciu": "somatie-de-plata",
"executor": "bej-exemplu",
"adrese": [
{ "lat": 44.4268, "lng": 26.1025, "eticheta": "Calea Victoriei 1, București", "detalii": "ap. 12" }
],
"destinatar": {
"tip": "persoana_juridica",
"nume": "OMV PETROM SA",
"cui": "RO1590082",
"regCom": "J1997008302407",
"telefon": "0212001111",
"email": "contact@exemplu.ro",
"adresa": "Str. Coralilor nr. 22, (PETROM CITY)",
"localitate": "Sector 1 Mun. București",
"judet": "MUNICIPIUL BUCUREȘTI",
"codPostal": "13329",
"sursa": "anaf"
},
"redactare": "client",
"document": {
"titlu": "Somație de plată",
"numeFisier": "somatie-4471.pdf",
"continut": "JVBERi0xLjcKMSAwIG9iago…"
},
"dosar": "4471/2026",
"referinta": "CRM-88213",
"mentiuni": "Destinatarul lucrează în schimbul de noapte."
}'HTTP/1.1 201 Created
{
"comanda": {
"referinta": "EXR-7K2M4Q",
"stare": "noua",
"executor": { "slug": "bej-exemplu", "birou": "BEJ Exemplu", "telefon": "…" },
"pret": { "totalBani": 35090, "tvaBani": 6090, "sursa": "tarif", "estimativ": false },
"plata": "credit",
"document": {
"titlu": "Somație de plată",
"url": null,
"fisiere": [
{
"numeFisier": "somatie-4471.pdf",
"octeti": 84213,
"sha256": "a1bd19bc44bc…",
"semnatElectronic": true,
"tipSemnatura": "ETSI.CAdES.detached",
"nrSemnaturi": 1
}
]
},
"referintaClient": "CRM-88213"
},
"creditRamasBani": 64910
}referinta este identificatorul comenzii peste tot mai departe. referintaClient este al tău, întors ca atare: cine trimite o mie de acte are deja un număr de dosar pentru fiecare și trebuie să-și regăsească comanda după el, nu după al nostru.
Licitație: birourile trimit prețul
Fluxul implicit al platformei, și de obicei cel mai ieftin. Deschizi o comandă fără să numești un birou; trimitem cererea celor mai apropiate 10 birouri competente pentru toate adresele din cerere, ele răspund cu prețul lor, iar tu accepți una. Licitația rămâne deschisă 3 zile.
Motivul pentru care există: majoritatea birourilor nu au tarif publicat, iar suma pe care POST /oferte o întoarce pentru ele este sursaPret: "plafon_legal" — maximul permis de lege, nu un preț pe care l-a promis cineva. O ofertă din licitație este.
1. Deschide licitația
Aceleași câmpuri ca la comanda directă, fără executor. Nu se debitează nimic aici și nu se verifică soldul — o licitație nu costă nimic până accepți.
curl -X POST https://executat.ro/api/v1/licitatii \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: dosar-4471-licitatie" \
-d '{
"serviciu": "somatie-de-plata",
"adrese": [
{ "lat": 44.4268, "lng": 26.1025, "eticheta": "Calea Victoriei 1, București", "detalii": "ap. 12" }
],
"destinatar": { "tip": "persoana_juridica", "nume": "OMV PETROM SA", "cui": "RO1590082", … },
"redactare": "client",
"document": { "titlu": "Somație", "numeFisier": "somatie.pdf", "continut": "JVBERi0xLjcK…" },
"referinta": "CRM-88213"
}'HTTP/1.1 201 Created
{
"comanda": {
"referinta": "EXR-7K2M4Q",
"stare": "licitatie",
"mod": "licitatie",
"executor": null,
"nrPagini": 3,
"pret": { "totalBani": 0, "sursa": "licitatie" },
"plata": "in_asteptare",
"licitatie": { "expiraLa": "2026-09-06T12:00:00.000Z", "nrInvitatii": 10, "nrOferte": 0 }
},
"invitate": 10,
"maxInvitatii": 10,
"zileLicitatie": 3,
"avertisment": null
}executor este null până accepți o ofertă, iar pret.totalBani este 0 — nu pentru că ar fi gratis, ci pentru că încă nu există un preț. Dacă invitate este 0, avertisment spune de ce: niciun birou nu e competent pentru toate adresele, deci comanda nu va primi oferte oricât ai aștepta.
La licitație, redactare: "client" cere actul ca document.continut, nu ca URL: birourile ofertează pe numărul de pagini, iar dintr-un link nu îl putem citi. Vezi actul.
2. Citește ofertele
Cele mai ieftine întâi. Ofertele retrase nu apar — nu mai pot fi acceptate, deci a le lista ar produce doar un 409 mai târziu.
curl https://executat.ro/api/v1/comenzi/EXR-7K2M4Q/oferte -H "Authorization: Bearer $TOKEN"{
"referinta": "EXR-7K2M4Q",
"stare": "licitatie",
"expiraLa": "2026-09-06T12:00:00.000Z",
"invitate": 10,
"oferte": [
{
"ofertaId": "6f1c…-…-…",
"totalBani": 28500,
"pretBani": 23554,
"tvaProcent": 21,
"termenZile": 3,
"mesaj": "Comunicăm în 48h dacă destinatarul e la adresă.",
"creatLa": "2026-09-04T08:11:02.000Z",
"executor": { "slug": "bej-exemplu", "birou": "BEJ Exemplu", "judet": "București", "distantaKm": 2.4 }
}
]
}3. Acceptă o ofertă
Aici se mișcă banii. Într-o singură tranzacție comanda primește preț, birou și plată, iar actul ajunge la biroul câștigător — și numai la el. Celelalte birouri află doar că licitația s-a încheiat.
curl -X POST https://executat.ro/api/v1/comenzi/EXR-7K2M4Q/accepta \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "ofertaId": "6f1c…-…-…" }'{
"comanda": { "referinta": "EXR-7K2M4Q", "stare": "acceptata", "executor": { "birou": "BEJ Exemplu", … },
"pret": { "totalBani": 28500, "sursa": "oferta" }, "plata": "credit" },
"birou": "BEJ Exemplu",
"totalBani": 28500,
"creditRamasBani": 71500
}Nu are nevoie de Idempotency-Key: oferta acceptată este înregistrată pe comandă, deci o a doua încercare cade pe o comandă care nu mai este în licitatie și primește 409, nu o a doua debitare.
Destinatarul actului
Un obiect, nu o linie de text. Executorul trebuie să identifice partea, să o poată contacta și să găsească ușa, iar un nume singur lăsa restul în seama biroului. Toate câmpurile de mai jos sunt obligatorii, în afară de judet, codPostal și — la persoană fizică — cui / regCom.
| Câmp | Regulă |
|---|---|
tip | „persoana_fizica” sau „persoana_juridica”. Implicit persoană fizică. |
nume | Numele persoanei sau denumirea exactă a societății. Minim 3 caractere. |
cui | Doar pentru persoane juridice, cu cifra de control verificată. Prefixul RO este acceptat și eliminat. Un CUI trimis pentru o persoană fizică este respins de o constrângere din bază, nu doar de validare. |
regCom | Numărul din Registrul Comerțului, opțional. |
telefon | Minim 9 cifre. |
email | Verificat ca formă. |
adresa | Adresa completă: stradă, număr, bloc, scară, etaj, apartament. |
localitate | Obligatorie. |
sursa | „anaf” dacă datele vin din registru, altfel „manual”. Se acceptă „anaf” doar când există și un CUI valid. |
Adresa destinatarului nu este adresa din căutare
Cele două răspund la întrebări diferite și nu au voie confundate. Punctul din adrese a decis ce birou este competent și cât costă deplasarea — pentru amândouă, o stradă ajunge. „Strada Rădulescu Drumea, Sector 4” nu este însă o adresă la care cineva poate suna la ușă. destinatar.adresa are numărul, blocul și apartamentul, și doar tu o știi.
Date de firmă din ANAF
GET /api/anaf?cui=RO1590082 întoarce denumirea, sediul social, numărul din Registrul Comerțului și starea din registru. Nu cere token, dar are limită de rată pe apelant — este o punte către un serviciu public cu o cerere pe secundă, nu un proxy de volum.
Merită folosit: un act comunicat pe o denumire greșită este o procedură care se poate ataca, iar denumirea exactă a unei societăți este publică și autoritativă acolo. Verifică și radiata — o comunicare către o firmă radiată nu produce efecte.
{
"ok": true,
"firma": {
"cui": "1590082",
"denumire": "OMV PETROM SA",
"nrRegCom": "J1997008302407",
"formaJuridica": "SOCIETATE COMERCIALĂ PE ACŢIUNI",
"stareInregistrare": "INREGISTRAT din data 23.10.1997",
"radiata": false,
"adresa": "Str. Coralilor, nr. 22, (PETROM CITY)",
"localitate": "Sector 1 Mun. Bucureşti",
"judet": "MUNICIPIUL BUCUREŞTI",
"codPostal": "13329",
"platitorTva": true
}
}Actul semnat electronic
Când trimiți redactare: "client", actul trebuie să vină odată cu comanda. Două forme, ambele valide:
document.continut — îl ținem noi
PDF-ul în base64. Îl stocăm și ajunge la birou odată cu comanda. Maxim 8 MB. Bun dacă nu ai unde să găzduiești fișierul sau dacă nu vrei să expui o adresă publică spre el.
document.url — îl ții tu
O adresă https către fișierul tău. Nimic nu se copiază la noi. Bun dacă ai deja un sistem de documente și vrei ca originalul să rămână acolo.
Ce înseamnă „semnatElectronic”
La încărcare ne uităm în fișier după o structură de semnătură și îți spunem ce am găsit, împreună cu tipSemnatura (de regulă ETSI.CAdES.detached, forma PAdES pe care o emit furnizorii din România) și sha256-ul conținutului.
Nu validăm semnătura. Câmpul spune că fișierul conține o semnătură, nu că ea este validă — pentru asta ar trebui verificat lanțul de certificate contra listelor de încredere ale UE, ceea ce noi nu facem. Validitatea o confirmă executorul judecătoresc, cu instrumentele lui. Nu construi un flux care tratează semnatElectronic: true ca pe o garanție.
Un fișier care nu este PDF este respins pe loc, cu cerere_invalida — verificăm octeții, nu extensia și nu content-type-ul, pentru că un .docx redenumit în .pdf este cel mai frecvent mod în care asta merge prost, iar el trebuie să eșueze la tine, nu la birou peste trei zile. Comanda nu se creează și creditul nu se atinge.
Idempotență
Un POST /comenzi care expiră în rețea a debitat deja contul, iar reacția firească la un timeout este reîncercarea. Trimite antetul Idempotency-Key cu o valoare a ta — numărul dosarului plus procedura merge foarte bine — și reîncercarea îți întoarce prima comandă în loc să plaseze a doua.
- Comandă nouă:
201 Created. - Reluare pe aceeași cheie:
200 OKplus antetulIdempotent-Replay: true. Nu se debitează a doua oară. - Cheia este a contului tău, deci nu te ciocnești de cheile altcuiva. Garanția o ține un index unic în baza de date, nu codul aplicației, așa că rezistă și când două reîncercări sosesc în aceeași clipă.
Credit, prețuri și anulări
Toate sumele sunt în bani
Numere întregi, niciodată zecimale. "totalBani": 35090 înseamnă 350,90 lei. Un total de factură ținut în virgulă mobilă derivă, iar aici derivă pe un serviciu juridic. Împarte la 100 doar când afișezi.
Stările comenzii
licitatie așteaptă oferte · acceptata ai ales o ofertă, s-a debitat · noua comandă directă, plătită · preluata · in_lucru · finalizata · respinsa · anulata · expirata (licitație închisă fără ofertă acceptată). Toate sunt valori valide pentru ?stare= la listare.
Ce înseamnă „sursaPret”
tarif — biroul ne-a comunicat acest preț. plafon_legal — nu ne-a comunicat, deci cifra este maximul pe care îl poate cere legal pentru procedură. Este o limită superioară, nu o cotație: onorariul real este de regulă mai mic și se stabilește la preluare.
oferta — prețul vine dintr-o ofertă acceptată în licitație. Singura dintre cele trei pe care a promis-o cineva, pentru lucrarea ta. licitatie apare cât timp licitația e deschisă și înseamnă că încă nu există preț.
Ce înseamnă „estimativ”
O distanță a trebuit aproximată, sau adresa cade în afara benzilor de deplasare publicate de birou. Comanda este validă și plătită, dar taxa de deplasare poate fi corectată de birou la preluare. Dacă integrarea ta emite facturi automat, tratează acest câmp ca pe un semnal.
Anulare
Se anulează din API în trei stări: licitatie (nu s-a debitat nimic, deci nu se întoarce nimic), acceptata (se stornează oferta plătită) și noua (comandă directă, se stornează). După ce biroul a preluat lucrarea, nu: s-a început lucrul, iar desfacerea lui este o discuție între oameni. Anularea repetată a aceleiași comenzi reușește și nu rambursează a doua oară.
Alimentarea creditului nu se face din API, intenționat: banii intră prin portal, unde se încasează cardul și se emite factura. Un endpoint care ar putea credita un sold ar fi un motiv mult mai interesant să furi un token.
Endpointuri
Baza: https://executat.ro/api/v1
- GETcitire
/api/v1/contContul, drepturile tokenului și soldul disponibil. Bun ca verificare de sănătate.
- GETcitire
/api/v1/serviciiCatalogul de proceduri, cu slugurile pe care le cer celelalte endpointuri și plafoanele legale.
- GETcitire
/api/v1/executoriDirectorul birourilor. Filtre: judet, camera, serviciu, online, q, limita, offset.
- GETcitire
/api/v1/adrese?q=…Adresă în text liber → punct, județ, localitate. Geocodează o dată, apoi trimite coordonate.
- GETsesiune
/api/profiluriIdentitățile de comandă salvate pe contul autentificat. Pe sesiunea de portal, nu pe token.
- GETpublic
/api/anaf?cui=…Denumirea, sediul social și starea unei firme din registrul ANAF. Fără token.
- POSTcitire
/api/v1/oferteCine e competent pentru adresele tale și cât cere fiecare, cu total și TVA. Nu scrie nimic.
- POSTcomenzi
/api/v1/licitatiiDeschide o licitație: comandă fără birou, invitații către cele mai apropiate 10 competente. Nu debitează.
- GETcitire
/api/v1/comenzi/{referinta}/oferteOfertele primite la o licitație, cele mai ieftine întâi. Fără cele retrase.
- POSTcomenzi
/api/v1/comenzi/{referinta}/acceptaAcceptă o ofertă: comanda primește preț, birou și plată. Mișcă bani.
- POSTcomenzi
/api/v1/comenziComandă directă la biroul ales, plătită din credit pe loc. Mișcă bani.
- GETcitire
/api/v1/comenziComenzile contului, ambele fluxuri, cele noi întâi. Filtre: stare, limita, offset.
- GETcitire
/api/v1/comenzi/{referinta}O comandă, cu istoricul stărilor prin care a trecut.
- POSTcomenzi
/api/v1/comenzi/{referinta}/anulareAnulează cât timp comanda este „licitatie”, „acceptata” sau „noua”. Returnează ce s-a debitat.
- GETcitire
/api/v1/creditSoldul și extrasul de cont, paginat cu inainteDe.
Erori
Toate erorile au aceeași formă. Ramifică pe cod, nu pe mesaj: textul este scris pentru om și se poate schimba, codul nu.
{
"eroare": {
"cod": "credit_insuficient",
"mesaj": "Creditul din cont nu acoperă această comandă. Alimentează contul și reia cererea.",
"detalii": { "necesarBani": 35090, "disponibilBani": 12000, "lipsaBani": 23090 }
}
}| Cod | HTTP | Când |
|---|---|---|
cerere_invalida | 400 | Lipsește un câmp sau are formatul greșit. `mesaj` spune care. |
adresa_invalida | 400 | O adresă nu a putut fi rezolvată sau cade în afara României. |
neautentificat | 401 | Lipsește antetul Authorization. |
token_invalid | 401 | Token inexistent, revocat sau oprit. |
token_expirat | 401 | Tokenul are dată de expirare și a trecut. Emite altul. |
cont_suspendat | 403 | Contul este suspendat sau nu are acces la API. |
permisiune_lipsa | 403 | Tokenul nu are dreptul cerut (de regulă „comenzi”). |
negasit | 404 | Procedura, biroul sau comanda nu există în contul tău. |
credit_insuficient | 402 | Soldul nu acoperă comanda. `detalii` spune cât lipsește. |
birou_incompetent | 409 | Biroul ales nu poate instrumenta la una dintre adrese. |
conflict | 409 | Comanda nu mai este în starea care permite operația. |
prea_multe_cereri | 429 | Ai depășit limita pe minut. Vezi antetul Retry-After. |
indisponibil | 503 | Ceva de partea noastră. Reia cererea. |
eroare_interna | 500 | Neașteptat. Cererea nu a fost înregistrată. |
Limite
120 cereri / minut
Per token. La depășire primești 429 și antetul Retry-After cu numărul de secunde. Dacă ai nevoie de mai mult pentru o migrare, scrie-ne — ridicăm limita pe token.
20 de adrese / comandă
O comandă merge la un singur birou, iar un birou competent pentru douăzeci de adrese împrăștiate prin țară nu prea există. Împarte pe județe: vei plăti mai puțin, pentru că deplasarea se calculează pe distanța reală.
Geocodarea e lentă
O adresă trimisă ca text trece prin geocoder, limitat la o cerere pe secundă. Rezolvă-le o dată prin /adrese, păstrează coordonatele și trimite apoi lat/lng.
Gata de integrare?
Intră în portal, deschide secțiunea API și generează-ți primul token — accesul se activează pe loc. Poți încerca oricând fluxul de ofertare fără cont, din formularul de pe prima pagină.
Generează un tokenAi întrebări despre integrare sau ai nevoie de o limită mai mare? Scrie-ne la info@executat.ro.
executat.ro este un serviciu de intermediere: nu suntem birou de executor judecătoresc. Comanda plasată prin API ajunge la biroul pe care îl alegi, iar procedura o instrumentează executorul judecătoresc, care rămâne responsabil pentru ea. Vezi termenii.