Guía: identificadores externos
Tu sistema tiene su número de pedido, de expediente o de factura. WAT lo guarda junto a la reserva para que los dos hablen del mismo servicio sin tablas intermedias.
El modelo
| Concepto | Detalle |
|---|---|
| Un enlace = (integración, entidad, id de WAT) → tu id | Cada integración tiene los suyos. El ERP y el CRM no se ven entre sí. |
| Único por integración | Dos reservas no comparten tu id. Repetirlo en otra reserva es 409 conflict. |
| Aparece en todas partes | Cada Booking de la API y de los webhooks trae external_id. GET /bookings?external_id=… busca por él. |
| Entidades | En v1 solo se escribe para reservas. Clientes, conductores y vehículos devuelven external_id en la lectura (null hasta que exista un endpoint para escribirlo). |
Cuándo guardarlo
En el momento en que tu sistema crea su registro: al procesar booking.created (si tu sistema abre expedientes por reserva) o al procesar booking.completed (si solo registra servicios hechos). Con Idempotency-Key puedes repetir la llamada sin miedo:
async function enlazar(watId, miId) {
const res = await fetch(`${API}/bookings/${watId}/external-id`, {
method: 'PUT',
headers: { ...h, 'Content-Type': 'application/json', 'Idempotency-Key': `link-${watId}-${miId}` },
body: JSON.stringify({ external_id: miId }),
});
if (res.status === 409) {
// miId ya apunta a OTRA reserva: casi siempre un duplicado en tu lado
const { error } = await res.json();
throw new Error(`conflicto: ${error.message} (${error.request_id})`);
}
if (!res.ok) throw new Error(`${res.status}`);
return res.json(); // { id, entity: 'booking', external_id, created_at, updated_at }
}Buscar por tu id
curl "https://wearetransfers.com/api/v1/bookings?external_id=VLC-2026-000123" \
-H "Authorization: Bearer $WAT_API_KEY"Devuelve una lista con esa reserva, o vacía. external_id anula los demás filtros de la lista.
Cambiar o quitar
PUTcon otro valor sobre la misma reserva lo sustituye.DELETE /bookings/{id}/external-idlo quita. Si no había,404.GET /bookings/{id}/external-idlo lee:external_id: nullsi no hay (no es un error).
Si guardas tu id nada más procesar, external_id: null en una reserva completada significa que se te escapó. La reconciliación mensual pasa a ser: recorre GET /bookings?status=completed&pickup_from… y procesa lo que venga con null. Ver Sincronizar servicios completados.
Reglas del valor
ASCII imprimible, de 1 a 200 caracteres. Vale FAC-2026/000123; no valen tildes, saltos de línea ni cadenas vacías (400 validation_error, details.field: "external_id").