En Ajustes → API e integraciones pulse «Clave nueva» y elija «Solo publicación de viajes». Empiece con una clave Prueba: lo que publique no aparece en la bolsa.
Ponga la clave en una variable de entorno, no en el código:
export GOCARGO_API_KEY="gc_test_..."curl https://gocargo.ro/api/v1/me \
-H "Authorization: Bearer $GOCARGO_API_KEY"La respuesta muestra la empresa, los permisos de la clave y el límite de solicitudes.
Envíe la carga con external_id = ID de su TMS. Si lo reenvía, lo actualizamos en lugar de crear otro (upsert), por lo que la sincronización es trivial.
La lista de sus cargas:
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-19",
"vehicle_kind": "prelata",
"weight_kg": 8000,
"price": 1450,
"currency": "EUR"
}'Cada solicitud lleva la cabecera Authorization: Bearer gc_live_… (sau gc_test_…). La dirección base es https://gocargo.ro/api/v1. Solo HTTPS.
X-Request-Id; envíelo cuando nos pida ayuda.Una solicitud sin el permiso necesario recibe 403 scope_missing.
| Permiso | Qué permite |
|---|---|
loads:read | Lee las cargas de la empresa |
loads:write | Publica, modifica y retira cargas |
trucks:read | Lee los camiones libres de la empresa |
trucks:write | Publica, modifica y retira camiones libres |
orders:read | Lee los pedidos |
orders:write | Cambie el estado de los pedidos y envíe la posición GPS |
marketplace:read | Buscar en la bolsa pública (cargas y camiones) |
webhooks:manage | Gestione los webhooks mediante la API |
export:read | Exportar datos (planes Business y 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 | Código | Cuándo |
|---|---|---|
| 400 | invalid_request | Datos no válidos; los detalles por campo están en «fields» |
| 401 | unauthorized | Clave ausente, incorrecta o revocada |
| 401 | key_expired | La clave ha caducado |
| 402 | plan_required | La función no está incluida en el plan de la empresa |
| 403 | forbidden | Acción no permitida para su empresa |
| 403 | scope_missing | A la clave le falta el permiso requerido (indicado en el mensaje) |
| 403 | ip_not_allowed | La solicitud procede de una IP que no está en la lista de la clave |
| 404 | not_found | El recurso no existe o no pertenece a la empresa |
| 409 | conflict | Estado incompatible o Idempotency-Key reutilizada con otro cuerpo |
| 429 | rate_limited | Demasiadas solicitudes; espere lo que indica Retry-After |
| 429 | quota_exceeded | Se ha agotado la cuota mensual de solicitudes de la empresa |
| 500 | server_error | Error por nuestra parte; reintente y envíenos X-Request-Id |
| Plan / licencia | Solicitudes por minuto, por clave | Solicitudes al mes, por empresa | Dominios |
|---|---|---|---|
| Pro | 60 | 50.000 | 1 |
| Business | 300 | 300.000 | 1 |
| Enterprise | 1200 | 2.000.000 | 3 |
| Integrador de software | 600 | 1.000.000 | 10 |
| Socio de bolsa / agregador | 1200 | 5.000.000 | 25 |
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Por encima del límite: 429 con Retry-After (secunde).X-Quota-Limit y X-Quota-Remaining; consume todas las claves, incluidas las de prueba. Paquetes adicionales y licencias comerciales: precios de la API.?limit=100&cursor=…, respuesta {data, next_cursor}. Para la sincronización utilice 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": "..."}}
]}Sobre cualquiera POST envíe la cabecera Idempotency-Key con un valor único (p. ej. un UUID). Si la red se cae y reintenta con el mismo valor, recibe exactamente la misma respuesta, sin una segunda carga. La respuesta se conserva 24 horas. El mismo valor con otro cuerpo → 409 conflict.
Añada una URL HTTPS en Ajustes → API e integraciones → Webhooks (o mediante POST /webhooks) y elija los eventos. El secreto whsec_… se muestra una sola vez.
| Evento | Cuándo |
|---|---|
load.created | Se ha publicado una carga |
load.updated | Se ha modificado una carga |
load.booked | Se ha reservado una carga |
load.withdrawn | Se ha retirado una carga |
quote.received | Ha recibido una oferta de precio |
order.created | Se ha creado un pedido |
order.status_changed | El pedido ha cambiado de estado |
order.document_added | Se ha añadido un documento al pedido (CMR, factura) |
order.position_updated | Se ha actualizado la posición del camión |
message.received | Ha recibido un mensaje |
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 para ignorar los duplicados.La cabecera GoCargo-Signature: t=<unix>,v1=<hex>, donde v1 = HMAC-SHA256 con el secreto del webhook (completo, con whsec_) sobre {t}.{corpul brut}. Rechace las firmas con más de 5 minutos de antigüedad.
# 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 "", 204Si al crearla marca «Firma HMAC obligatoria», recibe también un secreto de firma. Cada solicitud debe llevar además las cabeceras X-GoCargo-Timestamp (segundos unix) y X-GoCargo-Signature = HMAC-SHA256 en hexadecimal sobre {timestamp}.{METODĂ}.{cale}.{corp}.
cale es la ruta completa en el servidor más la consulta exacta tal como la envía (si existe), p. ej. /api/v1/loads sau /api/v1/loads?status=active. Para GET, el cuerpo está vacío (el mensaje termina con «.»).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-19"}).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, con conjunto ∈ loads, trucks, orders, quotes, reviews. La clave necesita export:read. Máximo 50.000 filas y 366 días por solicitud. El CSV tiene BOM UTF-8 y separador «;», para que se abra correctamente en 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"Sin código: Ajustes → Exportar datos.
No ponga nunca la clave API en HTML ni en JavaScript del navegador. Cualquiera que abra la página la ve (View Source, DevTools) y puede publicar en nombre de su empresa. La clave se queda solo en el servidor: el formulario envía a un script suyo y el script llama a 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 el script (solo usuarios autenticados en su sitio web, token CSRF) y configure GOCARGO_API_KEY en la configuración del servidor, no en el archivo. Lo ideal, una clave solo con loads:write y restricción por la IP del servidor.
La API está incluida en los planes Pro, Business y Enterprise. Empiece con una clave de prueba, sin riesgos.