Erori
API-ul folosește coduri HTTP standard și un body JSON consistent pentru erori.
Coduri de status
| Cod | Semnificație |
|---|---|
| 200 | Succes. |
| 201 | Resursa a fost creată. |
| 204 | Succes, fără body. |
| 400 | Cerere invalidă la nivel de protocol (rar — majoritatea problemelor de validare apar ca 422). |
| 401 | Autentificarea a eșuat. Vezi ghidul de autentificare. |
| 403 | Autentificat dar fără autorizație — permisiune lipsă, tenant suspendat, etc. |
| 404 | Resursa nu există sau nu aparține tenantului tău. |
| 422 | Validarea a eșuat. Body-ul conține mesajele de eroare per câmp. |
| 429 | Limita de rată depășită. Vezi limite de rată. |
| 500 | Eroare de server — încearcă din nou; dacă persistă, deschide un tichet cu id-ul cererii. |
Forma body-ului de eroare
Pentru erori care nu sunt de validare:
{
"error": "Descriere lizibilă a problemei."
}Pentru erori de validare (HTTP 422), forma standard Laravel:
{
"message": "The customer name field is required. (and 1 more error)",
"errors": {
"customer_name": [
"The customer name field is required."
],
"items.0.product_id": [
"The selected items.0.product_id is invalid."
]
}
}message conține primul mesaj de eroare (plus (and N more errors) când sunt mai multe); errors listează toate mesajele, grupate pe câmp. Construiește-ți validarea în jurul obiectului errors, nu al șirului message.
Idempotență
Majoritatea endpoint-urilor POST care creează resurse nu sunt idempotente — reîncercarea după o eroare de rețea poate crea duplicate. Folosește id-ul resursei rezultate pentru deduplicare în sistemul tău sau verifică existența resursei înainte de a reîncerca.
Excepție: POST /api/v1/billing/invoices face upsert după external_id, deci este sigur la reîncercare — același external_id actualizează rândul existent în loc să dubleze.