În Setări → API și integrări apăsați „Cheie nouă” și alegeți „Doar publicare curse”. Începeți cu o cheie Test: ce publicați nu apare în bursă.
Puneți cheia într-o variabilă de mediu, nu în cod:
export GOCARGO_API_KEY="gc_test_..."curl https://gocargo.ro/api/v1/me \
-H "Authorization: Bearer $GOCARGO_API_KEY"Răspunsul arată firma, permisiunile cheii și limita de cereri.
Trimiteți încărcătura cu external_id = ID-ul din TMS-ul vostru. Dacă îl retrimiteți, o actualizăm în loc să creăm alta (upsert), deci sincronizarea e trivială.
Lista încărcăturilor voastre:
curl "https://gocargo.ro/api/v1/loads?limit=20" \
-H "Authorization: Bearer $GOCARGO_API_KEY"curl -X POST https://gocargo.ro/api/v1/loads \
-H "Authorization: Bearer $GOCARGO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"external_id": "TMS-10045",
"origin_country": "RO",
"origin_city": "Cluj-Napoca",
"dest_country": "DE",
"dest_city": "Stuttgart",
"cargo": "Piese auto, 12 paleti",
"loading_date": "2026-10-18",
"vehicle_kind": "prelata",
"weight_kg": 8000,
"price": 1450,
"currency": "EUR"
}'Fiecare cerere poartă antetul Authorization: Bearer gc_live_… (sau gc_test_…). Adresa de bază este https://gocargo.ro/api/v1. Doar HTTPS.
X-Request-Id; trimiteți-l când ne cereți ajutor.O cerere fără permisiunea necesară primește 403 scope_missing.
| Permisiune | Ce permite |
|---|---|
loads:read | Citește încărcăturile firmei |
loads:write | Publică, modifică și retrage încărcături |
trucks:read | Citește camioanele libere ale firmei |
trucks:write | Publică, modifică și retrage camioane libere |
orders:read | Citește comenzile |
orders:write | Schimbă statusul comenzilor și trimite poziția GPS |
marketplace:read | Caută în bursa publică (încărcături și camioane) |
webhooks:manage | Gestionează webhook-urile prin API |
export:read | Exportă date (planurile Business și Enterprise) |
HTTP/1.1 400 Bad Request
X-Request-Id: 5f0c2e7a9b1d4c3e
Content-Type: application/json
{
"error": {
"code": "invalid_request",
"message": "Datele trimise nu sunt valide.",
"fields": { "loading_date": "Data de încărcare nu poate fi în trecut." }
}
}| HTTP | Cod | Când |
|---|---|---|
| 400 | invalid_request | Date invalide; detaliile pe câmp sunt în „fields” |
| 401 | unauthorized | Cheie lipsă, greșită sau revocată |
| 401 | key_expired | Cheia a expirat |
| 402 | plan_required | Funcția nu e inclusă în planul firmei |
| 403 | forbidden | Acțiune nepermisă pentru firma voastră |
| 403 | scope_missing | Cheii îi lipsește permisiunea cerută (numită în mesaj) |
| 403 | ip_not_allowed | Cererea vine de pe un IP care nu e în lista cheii |
| 404 | not_found | Resursa nu există sau nu e a firmei |
| 409 | conflict | Stare incompatibilă sau Idempotency-Key refolosit cu alt corp |
| 429 | rate_limited | Prea multe cereri; așteptați cât spune Retry-After |
| 429 | quota_exceeded | S-a terminat cota lunară de cereri a firmei |
| 500 | server_error | Eroare la noi; reîncercați și trimiteți-ne X-Request-Id |
| Plan / licență | Cereri pe minut, pe cheie | Cereri pe lună, pe firmă | Domenii |
|---|---|---|---|
| Pro | 60 | 50.000 | 1 |
| Business | 300 | 300.000 | 1 |
| Enterprise | 1200 | 2.000.000 | 3 |
| Integrator software | 600 | 1.000.000 | 10 |
| Partener bursă / agregator | 1200 | 5.000.000 | 25 |
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Peste limită: 429 cu Retry-After (secunde).X-Quota-Limit și X-Quota-Remaining; o consumă toate cheile, inclusiv cele de test. Pachete suplimentare și licențe comerciale: prețuri API.?limit=100&cursor=…, răspuns {data, next_cursor}. Pentru sincronizare folosiți updated_since.curl -X POST https://gocargo.ro/api/v1/loads/bulk \
-H "Authorization: Bearer $GOCARGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"items": [ {...}, {...} ]}'
# Răspuns: fiecare element are rezultatul lui
{"results": [
{"index": 0, "ok": true, "ref": "GC1A2B3C4D"},
{"index": 1, "ok": false, "error": {"code": "invalid_request", "message": "..."}}
]}Pe orice POST trimiteți antetul Idempotency-Key cu o valoare unică (ex. un UUID). Dacă rețeaua cade și reîncercați cu aceeași valoare, primiți exact același răspuns, fără o a doua încărcătură. Răspunsul se păstrează 24 de ore. Aceeași valoare cu alt corp → 409 conflict.
Adăugați un URL HTTPS în Setări → API și integrări → Webhooks (sau prin POST /webhooks) și alegeți evenimentele. Secretul whsec_… se afișează o singură dată.
| Eveniment | Când |
|---|---|
load.created | O încărcătură a fost publicată |
load.updated | O încărcătură a fost modificată |
load.booked | O încărcătură a fost rezervată |
load.withdrawn | O încărcătură a fost retrasă |
quote.received | Ați primit o ofertă de preț |
order.created | S-a creat o comandă |
order.status_changed | Comanda și-a schimbat statusul |
order.document_added | S-a adăugat un document la comandă (CMR, factură) |
order.position_updated | S-a actualizat poziția camionului |
message.received | Ați primit un mesaj |
POST /gocargo/webhook HTTP/1.1
Content-Type: application/json
GoCargo-Signature: t=1760180000,v1=8f3c...e91a
{
"id": "evt_2b7f0c9e1a4d",
"type": "order.status_changed",
"created_at": "2026-10-11T09:30:00Z",
"data": { ... }
}id ca să ignorați dublurile.Antetul GoCargo-Signature: t=<unix>,v1=<hex>, unde v1 = HMAC-SHA256 cu secretul webhook-ului (întreg, cu whsec_) peste {t}.{corpul brut}. Respingeți semnăturile mai vechi de 5 minute.
# pip install flask
import hashlib
import hmac
import os
import time
from flask import Flask, abort, request
SECRET = os.environ["GOCARGO_WEBHOOK_SECRET"] # whsec_..., întreg
app = Flask(__name__)
def verify(header: str, body: bytes, tolerance: int = 300) -> bool:
parts = dict(p.strip().split("=", 1) for p in header.split(",") if "=" in p)
t, sig = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > tolerance:
return False
expected = hmac.new(SECRET.encode(), t.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
@app.post("/gocargo/webhook")
def webhook():
# Semnătura se calculează pe corpul BRUT, exact cum a sosit.
if not verify(request.headers.get("GoCargo-Signature", ""), request.get_data()):
abort(400)
event = request.get_json()
print(event["type"], event["data"])
return "", 204Dacă la creare bifați „Semnătură HMAC obligatorie”, primiți și un secret de semnare. Fiecare cerere trebuie să aibă în plus antetele X-GoCargo-Timestamp (secunde unix) și X-GoCargo-Signature = HMAC-SHA256 în hex peste {timestamp}.{METODĂ}.{cale}.{corp}.
cale este calea completă de pe server plus query-ul exact cum îl trimiteți (dacă există), ex. /api/v1/loads sau /api/v1/loads?status=active. Pentru GET, corpul e gol (mesajul se termină cu „.”).import hashlib
import hmac
import json
import os
import time
import requests
ORIGIN = "https://gocargo.ro"
PATH = "/api/v1/loads"
KEY = os.environ["GOCARGO_API_KEY"]
SIGNING_SECRET = os.environ["GOCARGO_SIGNING_SECRET"]
body = json.dumps({"origin_city": "Cluj-Napoca", "dest_country": "DE", "dest_city": "Stuttgart",
"cargo": "Piese auto", "loading_date": "2026-10-18"}).encode()
ts = str(int(time.time()))
message = ts.encode() + b".POST." + PATH.encode() + b"." + body
signature = hmac.new(SIGNING_SECRET.encode(), message, hashlib.sha256).hexdigest()
r = requests.post(ORIGIN + PATH, data=body, timeout=30, headers={
"Authorization": "Bearer " + KEY,
"Content-Type": "application/json",
"X-GoCargo-Timestamp": ts,
"X-GoCargo-Signature": signature,
})
print(r.status_code, r.text)GET /export/{set}?format=csv|xlsx|json&from=AAAA-LL-ZZ&to=AAAA-LL-ZZ, cu set ∈ loads, trucks, orders, quotes, reviews. Cheia are nevoie de export:read. Maximum 50.000 de rânduri și 366 de zile pe cerere. CSV-ul are BOM UTF-8 și separator „;”, ca să se deschidă corect în Excel.
curl -o comenzi.xlsx \
"https://gocargo.ro/api/v1/export/orders?format=xlsx&from=2026-01-01&to=2026-06-30" \
-H "Authorization: Bearer $GOCARGO_API_KEY"Fără cod: Setări → Export date.
Nu puneți niciodată cheia API în HTML sau în JavaScript din browser. Oricine deschide pagina o vede (View Source, DevTools) și poate publica în numele firmei voastre. Cheia stă doar pe server: formularul trimite la un script al vostru, iar scriptul cheamă GoCargo.
<!-- formularul din site: trimite la scriptul PHP de pe serverul vostru, NU la GoCargo -->
<form method="post" action="/publica.php">
<input name="origin_city" placeholder="De la" required>
<input name="dest_city" placeholder="Până la" required>
<input name="dest_country" value="RO" maxlength="2">
<input name="cargo" placeholder="Marfă" required>
<input name="loading_date" type="date" required>
<button>Publică pe GoCargo</button>
</form><?php // publica.php — cheia stă doar aici, pe server
$key = getenv('GOCARGO_API_KEY');
$load = [
'origin_country' => 'RO', 'origin_city' => $_POST['origin_city'] ?? '',
'dest_country' => strtoupper($_POST['dest_country'] ?? 'RO'), 'dest_city' => $_POST['dest_city'] ?? '',
'cargo' => $_POST['cargo'] ?? '', 'loading_date' => $_POST['loading_date'] ?? '',
];
$ch = curl_init('https://gocargo.ro/api/v1/loads');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key, 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($load, JSON_UNESCAPED_UNICODE)]);
$res = curl_exec($ch);
http_response_code(curl_getinfo($ch, CURLINFO_HTTP_CODE) ?: 502);
header('Content-Type: application/json');
echo $res;Protejați scriptul (doar utilizatori autentificați în site-ul vostru, token CSRF) și setați GOCARGO_API_KEY în configurarea serverului, nu în fișier. Ideal, o cheie doar cu loads:write și restricție pe IP-ul serverului.
API-ul e inclus în planurile Pro, Business și Enterprise. Începeți cu o cheie de test, fără riscuri.