ORBI / API

Integración v1

Esta página es pública. Un ERP u otra plataforma autentica con una API key orb_… emitida para un solo tenant. El tenant sale del secreto, nunca del body.

Réplica en el repositorio: docs/integracion.md.

1. Base URL

https://orbi.orbitrack.us

Las rutas de producto viven en /api/v1.

2. Autenticación

Authorization: Bearer orb_…

Orbi hashea la key (SHA-256) y carga el tenant asociado. No envíes tenant_id en el JSON. Una key de la organización A no puede leer datos de B.

3. Cómo obtener la key

  • Superadmin: /platform → Organizaciones → Generar API key.
  • Admin del tenant: POST /api/v1/api-keys (scope keys:manage).

El secreto solo viaja en el 201. Después solo verás el prefijo.

4. Scopes

ScopeUso
assets:readListar activos y leer fotos de catálogo (lista + binario)
assets:writeCrear y editar activos
images:writeFotos de catálogo (máx. 5)
verifyVerify 1:1
identifyIdentify 1:N
keys:manageGestionar keys del tenant (opcional para un ERP)

5. Errores

{ "error": { "code": "forbidden", "message": "…" } }

Códigos habituales: unauthorized, forbidden, tenant_suspended, invalid_body, not_found, rate_limited, serial_taken (409), object_missing (409, el PUT no dejó el archivo).

6. Equivalencia SKU = modelo

Un modelo / SKU (model) puede tener varios seriales. Cada serial es único en Orbi (dentro del tenant): no se repite en otro modelo.

ConceptoCampo Orbi
Modelo / SKU (1 → N seriales)model
Serial (único en el tenant)external_serial_id
Unidad = un serialuna fila en assets
Serie física / OCR (opcional)serial_number

No uses el SKU como serial. En Orbitrack: products.sku → model; cada product_serials.serial_number → un external_serial_id.

7. Crear y listar un activo

curl -sS https://orbi.orbitrack.us/api/v1/assets \
  -H "Authorization: Bearer $ORBI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_serial_id": "ERP-10042",
    "serial_number": "SN-10042",
    "asset_type": "compressor",
    "model": "CIL-15KG"
  }'

curl -sS "https://orbi.orbitrack.us/api/v1/assets?q=ERP-10042" \
  -H "Authorization: Bearer $ORBI_KEY"

8. Foto de catálogo

Hasta 5 slots. Tres pasos: URL firmada → PUT al Blob privado (usa los headers de la respuesta) → complete (202). complete comprueba que el objeto exista; si el PUT no dejó archivo: 409 object_missing.

La foto queda disponible enseguida. occupied es true si hay archivo. processing_status puede seguir en pending mientras se indexa (embeddings). Verify e identify necesitan processed.

Las URLs firmadas (read_url / preview_url) son privadas y caducan (~15 min). Para mostrar la foto en una UI, pide el binario con la API key; no uses la URL de Blob como <img src> anónimo.

curl -sS https://orbi.orbitrack.us/api/v1/assets/$ASSET_ID/images/upload-url \
  -H "Authorization: Bearer $ORBI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slot":1,"mime_type":"image/jpeg"}'

curl -sS -X PUT "$UPLOAD_URL" -H "Content-Type: image/jpeg" --data-binary @foto.jpg

curl -sS https://orbi.orbitrack.us/api/v1/assets/$ASSET_ID/images/complete \
  -H "Authorization: Bearer $ORBI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slot":1,"object_key":"'"$OBJECT_KEY"'","idempotency_key":"img-erp-1"}'

# Lista (snake_case): occupied, processing_status, read_url, preview_url
curl -sS https://orbi.orbitrack.us/api/v1/assets/$ASSET_ID/images \
  -H "Authorization: Bearer $ORBI_KEY"

# Binario del slot 1 (o del image_id). También .../images/1/preview
curl -sS https://orbi.orbitrack.us/api/v1/assets/$ASSET_ID/images/1 \
  -H "Authorization: Bearer $ORBI_KEY" \
  -o slot-1.jpg

9. Verify 1:1

Sube la consulta con POST /api/v1/objects/query-upload-url, luego verify y haz poll a GET /api/v1/requests/:id hasta processed. Decisión: positive, negative o inconclusive.

curl -sS https://orbi.orbitrack.us/api/v1/verify \
  -H "Authorization: Bearer $ORBI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_serial_id": "ERP-10042",
    "image_object_key": "'"$OBJECT_KEY"'",
    "idempotency_key": "verify-erp-001"
  }'

curl -sS https://orbi.orbitrack.us/api/v1/requests/$REQUEST_ID \
  -H "Authorization: Bearer $ORBI_KEY"

10. Identify 1:N

Solo busca dentro del tenant de la key. Misma cola asíncrona (202 + poll). El índice visual usa Cohere embed-v4.0 (1024-d) y umbrales threshold_cohere_v2. model_version es el modelo de embeddings, no el SKU. Un positivo exige que el número grabado coincida con el serial; si el modelo tiene gemelos y no se lee el grabado, la respuesta es stamp_needed.

curl -sS https://orbi.orbitrack.us/api/v1/identify \
  -H "Authorization: Bearer $ORBI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image_object_key": "'"$OBJECT_KEY"'",
    "idempotency_key": "identify-001",
    "top_k": 5
  }'

11. Idempotencia, límites y suspensión

  • Campo idempotency_key (mín. 8) en complete, verify e identify. La misma clave en el mismo tenant reutiliza el trabajo.
  • No hay rate limits activos por ahora. El código rate_limited / 429 queda reservado.
  • Tenant suspendido → 403 tenant_suspended.

12. No loguear secretos ni imágenes

No escribas el secreto ni el binario de las fotos en logs, APM o tickets. Las URLs de Blob son privadas y caducan; el GET binario del slot no depende de esa firma.