Saltar al contenido
Documentación · API v1

Mover la lonja por API.

REST sobre HTTPS. JSON in, JSON out. OpenAPI 3.1 público. Versionada por URL (/v1/). Sandbox idéntico a producción para probar sin riesgo.

Base URL: https://api.lalonja.market/v1  ·  Sandbox: https://sandbox.api.lalonja.market/v1

Autenticación

Toda petición requiere una API key en la cabecera Authorization. Las keys se generan en el panel de tu organización (Ajustes → API). Cada key tiene un scope (read, trade, admin) y un IP allowlist opcional.

# Petición autenticada
curl https://api.lalonja.market/v1/lots \
  -H "Authorization: Bearer lk_live_8f2A...j7Q3" \
  -H "X-Idempotency-Key: 9f3b-4e2a-..."

Las keys de sandbox empiezan por lk_test_ y las de producción por lk_live_. Nunca expongas una key en código cliente — todas las llamadas deben hacerse desde tu backend.

SDKs oficiales

Tres SDKs mantenidos por el equipo de lalonja. Tipados, documentados, con cobertura de tests >90 %. Si necesitas otro lenguaje, la API REST es trivial de consumir directamente.

Errores y rate limits

Códigos HTTP estándar. Todos los errores devuelven un cuerpo JSON con error.code, error.message y error.request_id para soporte. Rate limit: 600 peticiones/min por API key (escalable bajo demanda en plan Forward). Las cabeceras X-RateLimit-Remaining y X-RateLimit-Reset indican estado.

Listar lotes

GET/v1/lots

Devuelve los lotes accesibles para tu organización, paginados por cursor. Filtrable por estado, sector, productor o ventana temporal.

ParámetroTipoDescripción
statusstringdraft, open, matched, settled, cancelled
sectorstringhorto, fruta, despensa
producer_idstringFiltra por productor concreto.
limitintHasta 100. Default 25.
cursorstringCursor de paginación.
curl -G https://api.lalonja.market/v1/lots \
  --data-urlencode "status=open" \
  --data-urlencode "sector=horto" \
  --data-urlencode "limit=10" \
  -H "Authorization: Bearer lk_live_8f2A..."

Respuesta · 200 OK

{
  "data": [
    {
      "id": "lot_8f3a2b9c4d1e",
      "sector": "horto",
      "variety": "tomate-rosa",
      "weight_kg": 22000,
      "origin": { "farm": "Coop. Tomate de Conil", "municipality": "Conil de la Frontera" },
      "reserve_price": 2.80,
      "currency": "EUR",
      "unit": "kg",
      "status": "open",
      "auction": { "id": "auc_4e8a...", "closes_at": "2026-04-29T08:30:00Z" },
      "lca_url": "https://api.lalonja.market/v1/lots/lot_8f.../lca"
    }
  ],
  "next_cursor": "c_92Ka..."
}

Crear lote

POST/v1/lots

Sólo cuentas con scope trade y rol productor. La trazabilidad LCA puede adjuntarse al crear el lote o subirse después; sin LCA el lote no puede pasar a estado open.

{
  "sector": "horto",
  "variety": "tomate-rosa",
  "weight_kg": 2400,
  "reserve_price": 5.85,
  "unit": "kg",
  "harvest_date": "2026-04-22",
  "auction": {
    "type": "sealed_bid",
    "opens_at": "2026-04-29T07:00:00Z",
    "closes_at": "2026-04-29T08:30:00Z"
  },
  "lca": { "reference": "LCA-2026-0481" }
}

Pujar en una subasta

POST/v1/auctions/:id/bids

Sólo accesible si tu organización es comprador verificado y tiene crédito disponible suficiente para cubrir la puja. Las pujas son inmutables: no se pueden retirar una vez aceptadas.

{
  "price_per_unit": 43.20,
  "quantity_kg": 87.4,
  "valid_until": "2026-04-29T08:30:00Z"
}
Idempotencia obligatoria: toda llamada que cree o modifique estado debe enviar la cabecera X-Idempotency-Key con un UUID único. Reintentos con la misma key devuelven el mismo resultado sin efectos secundarios.

Crear contrato forward

POST/v1/forwards

Crea un contrato forward propuesto. La firma se realiza en una segunda llamada con firma electrónica conforme al Reglamento UE 910/2014 (eIDAS). Hasta que ambas partes firman, el forward está en estado proposed.

{
  "counterparty_id": "org_4d2a9f1b",
  "sector": "horto",
  "variety": "tomate-rosa",
  "quantity_kg": 120000,
  "price_per_kg": 5.78,
  "delivery_window": { "start": "2026-11-01", "end": "2026-11-30" },
  "escrow_pct": 0.20
}

Trazabilidad LCA del lote

GET/v1/lots/:id/lca

Devuelve el ciclo de vida del lote en JSON-LD compatible con CSRD ESRS E1–E5 y SBTi Scope 3 categoría 1. Incluye la huella de carbono verificada por auditor externo, el origen geográfico georreferenciado y la cadena de custodia.

{
  "@context": "https://schema.lalonja.market/lca/v1",
  "lot_id": "lot_8f3a2b9c",
  "co2e_kg_per_unit": 3.42,
  "audit": {
    "auditor": "external_eu_accredited",
    "reference": "LCA-2026-0481",
    "audited_at": "2026-04-23T14:22:00Z"
  },
  "chain_of_custody": [
    { "step": "capture", "location": { "lat": 36.275, "lon": -6.103 }, "at": "2026-04-22T05:14:00Z" },
    { "step": "landing", "port": "Conil", "at": "2026-04-22T11:30:00Z" },
    { "step": "auction", "at": "2026-04-22T18:45:00Z" }
  ]
}

Webhooks · Eventos

Configura un endpoint HTTPS en Ajustes → Webhooks. Recibirás un POST por cada evento suscrito con cabeceras de firma HMAC-SHA256 que debes verificar. Reintentos automáticos con backoff exponencial durante 24h si tu endpoint no responde 2xx.

Verificar firma HMAC

Cada webhook incluye X-Lalonja-Signature: t=<ts>,v1=<hex>. Calcula HMAC-SHA256 sobre {ts}.{rawBody} con tu webhook secret y compara con v1. Tolera ±5 minutos en ts.

import crypto from 'node:crypto';

function verify(rawBody, header, secret) {
  const [t, v1] = header.split(',').map(p => p.split('=')[1]);
  const sig = crypto.createHmac('sha256', secret)
    .update(`${t}.${rawBody}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(v1));
}
OpenAPI 3.1 spec: https://api.lalonja.market/v1/openapi.json · Postman collection: disponible en postman.com/lalonja