Documentație API
Cotații
Primul pas al fluxului. Descrii expedierea o singură dată și primești prețul fiecărui curier pentru ea, împreună cu identificatorii de care ai nevoie la pașii următori.
Două rute, scopuri diferite
| Rută | Salvează ceva? | Când o folosești |
|---|---|---|
POST /public/awb/quotes | Da — creează o cerere de cotație pe contul tău | Când intenționezi să creezi expediția. Doar aceste cotații pot fi selectate mai târziu. |
POST /public/awb/quick-quotes | Nu | Când afișezi doar prețuri — un calculator de transport la coș, de exemplu. |
Corpul cererii este identic pentru amândouă. Diferența este că quick-quotes nu cere autentificare și nu întoarce identificatori, deci din el nu poți continua spre AWB.
Creare cerere de cotație
/public/awb/quotesBearer JWT120/minCorpul se trimite la nivelul de sus. Nu îl împacheta într-un obiect createQuoteRequestDto — API-ul respinge proprietățile necunoscute cu 400.
{
"sender": {
"name": "Firma Mea SRL",
"isCompany": true,
"companyName": "Firma Mea SRL",
"cui": "RO12345678",
"email": "logistica@firma.ro",
"phoneCountryCode": "+40",
"phoneNSN": "700000000",
"address": {
"country": "Romania",
"county": "BUCURESTI",
"city": "BUCURESTI",
"postcode": "010061",
"street": "Calea Victoriei",
"streetNumber": "10"
}
},
"recipient": {
"name": "Ion Popescu",
"phoneCountryCode": "+40",
"phoneNSN": "700000001",
"address": {
"country": "Romania",
"county": "CLUJ",
"city": "CLUJ-NAPOCA",
"postcode": "400114",
"street": "Strada Memorandumului",
"streetNumber": "5",
"apartment": "12"
}
},
"content": {
"packages": [
{
"weight": 2.4,
"length": 40,
"width": 30,
"height": 20,
"packageType": "package"
}
]
},
"service": {
"saturdayDelivery": false,
"openOnDelivery": false,
"cod": {
"amount": 250,
"bankAccount": "RO49AAAA1B31007593840000",
"collector": "CLIENT"
},
"insurance": { "amount": 500 }
},
"paymentInfo": { "courierServicePayer": "SENDER" },
"packageDescription": "Carti",
"shipmentNote": "Sunati inainte de livrare",
"externalRef": "API-10023"
}{
"quoteRequest": {
"id": "3f9c1a34-7b2e-4d81-9f05-6c1e8a4b2d70",
"packageDescription": "Carti",
"createdAt": "2026-10-28T09:00:00.000Z",
"updatedAt": "2026-10-28T09:00:00.000Z"
},
"courierQuotes": [
{
"id": "b7e22d90-3c14-4a6f-8e09-1d5b7c2f4a83",
"courierName": "Dpd",
"amount": 18.95,
"currency": "RON",
"deliveryType": "DOOR_TO_DOOR",
"isLockerQuote": false,
"isDisabled": false,
"expiresAt": "2026-10-29T09:00:00.000Z",
"quoteRequestId": "3f9c1a34-7b2e-4d81-9f05-6c1e8a4b2d70",
"createdAt": "2026-10-28T09:00:00.000Z",
"updatedAt": "2026-10-28T09:00:00.000Z",
"standardAmount": 21.05,
"originalAmount": 21.05,
"discountPercent": 10,
"discountApplied": true,
"discountLabel": "Prima comanda"
},
{
"id": "c9f1a7b2-5d83-4e20-bc17-902f6a1d3e45",
"courierName": "GLS",
"amount": 0,
"currency": "RON",
"deliveryType": "DOOR_TO_DOOR",
"isLockerQuote": false,
"isDisabled": true,
"expiresAt": "2026-10-29T09:00:00.000Z",
"quoteRequestId": "3f9c1a34-7b2e-4d81-9f05-6c1e8a4b2d70",
"createdAt": "2026-10-28T09:00:00.000Z",
"updatedAt": "2026-10-28T09:00:00.000Z",
"error": {
"message": "Valoare declarata indisponibila la acest curier"
}
}
]
}Fiecare câmp, cu tipul și limitele lui, este descris în dicționarul de date. Pe scurt, ai nevoie de: expeditor, destinatar, cel puțin un pachet, blocul service, plătitorul transportului și o descriere a conținutului.
Citirea răspunsului
Ce reții
quoteRequest.id— îl folosești la pașii 2, 3 și 4.courierQuotes[].idal cotației alese — îl trimiți la pasul 2.
Câmpurile unei cotații
| Câmp | Tip | Cerut | Descriere |
|---|---|---|---|
courierName | string | mereu | Numele curierului, așa cum îl întoarce și GET /public/couriers. |
amount | number | mereu | Prețul pe care îl plătești, în RON, cu reducerile aplicate. Este 0 pe o cotație dezactivată. |
isDisabled | boolean | mereu | true înseamnă că acest curier nu poate executa expedierea. Nu poate fi selectată. |
error.message | string | când isDisabled | Motivul refuzului, formulat pentru a fi arătat utilizatorului. |
error.code | string | opțional | Prezent doar când refuzul poate fi ridicat. Singura valoare de astăzi este RECIPIENT_FIELDS_REQUIRED, însoțită de error.missingRecipientFields — câmpurile pe care curierul le cere și destinatarul nu le are (de pildă ["email"] pentru livrare în locker Sameday). |
deliveryType | string | mereu | DOOR_TO_DOOR, DOOR_TO_LOCKER, LOCKER_TO_DOOR sau LOCKER_TO_LOCKER. |
isLockerQuote | boolean | mereu | Expedierea atinge un locker la cel puțin un capăt. |
expiresAt | string | mereu | Momentul după care cotația nu mai poate fi folosită. În prezent, 24 de ore de la emitere. |
standardAmount | number | null | opțional | Prețul la tariful standard, pentru comparație. Prezent doar când diferă de amount. |
originalAmount | number | null | opțional | Prețul înainte de reducerea promoțională. Prezent doar când s-a aplicat una. |
discountPercent | number | null | opțional | Procentul reducerii, alături de discountApplied și discountLabel. |
openOnDeliveryUnsupported | boolean | null | opțional | Ai cerut deschidere la livrare, dar acest curier nu o duce până la destinatar. Cotația rămâne validă — doar serviciul lipsește. |
Niciodată „cel mai ieftin” fără filtru
O cotație dezactivată vine cu amount: 0. Dacă sortezi crescător fără să filtrezi, ea câștigă de fiecare dată și pasul următor eșuează.
// Corect: filtrează înainte de a sorta.
const usable = response.courierQuotes.filter(q => !q.isDisabled);
if (usable.length === 0) {
throw new Error('Niciun curier nu poate duce acest colet');
}
const cheapest = usable.reduce((a, b) => (a.amount <= b.amount ? a : b));
// Greșit: o cotație dezactivată are amount 0 și câștigă mereu.
// const cheapest = response.courierQuotes.reduce(
// (a, b) => (a.amount <= b.amount ? a : b)
// );Expirarea cotației
Cotațiile sunt valabile 24 de ore. Dacă încerci să creezi expediția după expiresAt, apelul răspunde cu 410 Gone și mesajul „This quote has expired, please get a new one”. Reia de la pasul 1: prețurile curierilor se pot schimba între timp, deci o cotație veche nu poate fi prelungită.
Cotații rapide
/public/awb/quick-quotespublic120/minAcelași corp de cerere, răspuns fără identificatori. Nimic nu este salvat.
{
"courierQuotes": [
{
"courierName": "Dpd",
"slug": "dpd",
"amount": 18.95,
"currency": "RON",
"deliveryType": "DOOR_TO_DOOR",
"isLockerQuote": false
}
]
}Răspunsul poartă în plus slug, util dacă afișezi logo-uri de curier. Nu poartă id, pentru că nu există nimic de selectat.
Expedieri cu lockere
Pentru predare sau livrare în locker, trimite în cerere perechea originLockerId + originCourierId, respectiv destinationLockerId + destinationCourierId. Identificatorii se iau din rutele de puncte de ridicare.
Ai nevoie de ajutor?
Dacă un curier apare dezactivat și nu înțelegi de ce, trimite-ne corpul cererii și câmpul error din cotația respectivă.
Contactează-ne