Harvis API · v1

API Enterprise

Integre ERP, BI y sistemas operativos con datos productivos de Harvis. Cada solicitud se limita por empresa, matriz, productor asociado, finca, canal y scope.

Quickstart

  1. 1.Solicite que Harvis habilite el acceso a la API enterprise para su organización.
  2. 2.Un administrador crea una API key desde Configuración → API Enterprise.
  3. 3.Guarde la key en un gestor de secretos de servidor.
  4. 4.Pruebe la organización asociada a la credencial.

Base URL de producción

Base URL
https://api.harvis.app
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"


curl "${HARVIS_API_URL}/v1/organization" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"

¿Tu empresa ya está habilitada?

Un administrador puede crear, rotar o revocar credenciales desde Configuración → API Enterprise.

Administrar API keys

¿No ves acceso a la API?

La API Enterprise debe habilitarse explícitamente para tu empresa antes de crear credenciales.

Solicitar habilitación por WhatsApp

Authentication y API keys

Envíe la key con Bearer authentication. No use ni exponga la service role de Supabase, ni una key Harvis desde código de navegador.

HTTP header
Authorization: Bearer ${HARVIS_API_KEY}

Scopes y aislamiento matriz/asociados

La key define scopes como farms:read, orders:read o products:write. Una matriz puede consultar sus productores asociados; un productor solo puede consultar su propia empresa. Un organization_id fuera del alcance devuelve acceso denegado.

Paginación y errores

Los listados aceptan limit entre 1 y 100 y retornan page.next_cursor. Reenvíe ese cursor sin modificarlo.

Página siguiente
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"


curl "${HARVIS_API_URL}/v1/farms?limit=50&cursor=$NEXT_CURSOR" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
  • 400: parámetro inválido.
  • 401: API key inválida, revocada o empresa sin acceso API.
  • 403: scope insuficiente o empresa fuera de alcance.
  • 404: recurso no visible para la credencial.
  • 503: servicio temporalmente no disponible; reintente con backoff.

Organización y productores

Navegue la empresa raíz y, para una matriz, sus productores asociados.

GET/v1/organization

Obtener organización

Devuelve la empresa raíz asociada a la API key.

Scope requeridoorganization:read
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"


curl "${HARVIS_API_URL}/v1/organization" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": {
    "id": "empresa-uuid",
    "name": "Cooperativa Andina",
    "country": { "id": "pais-uuid", "name": "Colombia", "code": "CO" },
    "enterprise": { "is_matrix": true }
  },
  "request_id": "req_01H..."
}
GET/v1/associated-producers

Listar productores asociados

Disponible únicamente cuando la organización de la key es una matriz.

Scope requeridoassociated_producers:read
ParámetroUbicaciónDescripción
limitqueryCantidad entre 1 y 100.
cursorqueryCursor de la página anterior.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"


curl "${HARVIS_API_URL}/v1/associated-producers?limit=50" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "id": "productor-uuid", "name": "Finca La Esperanza" }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}

Use el id retornado como organization_id al consultar fincas, lotes, cultivos, registros o contactos.

Fincas, lotes, cultivos y registros

Datos productivos filtrados por empresa autorizada, productor asociado y finca.

GET/v1/farms

Listar fincas

Incluye ubicación, información adicional y códigos de finca usados en integraciones.

Scope requeridofarms:read
ParámetroUbicaciónDescripción
organization_idqueryProductor asociado dentro del alcance de la matriz.
limitqueryCantidad entre 1 y 100.
cursorqueryCursor de la página anterior.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# organization_id: ID del productor asociado retornado por GET /v1/associated-producers
export ORGANIZATION_ID="uuid-del-productor-asociado"

curl "${HARVIS_API_URL}/v1/farms?organization_id=${ORGANIZATION_ID}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{
    "id": "finca-uuid",
    "name": "La Esperanza",
    "country": { "name": "Colombia", "code": "CO" },
    "location": { "geometry": { "type": "Point", "coordinates": [-75.5, 5.1] } },
    "additional_information": { "codigo_up": "UP-01" },
    "codes": { "codigo_up": "UP-01" }
  }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}

Con una key de matriz, omite organization_id para incluir su empresa y todo el alcance asociado. Para traer solo un productor, usa su ID como organization_id.

GET/v1/plots

Listar lotes

Consulta lotes de una empresa o de una finca concreta.

Scope requeridoplots:read
ParámetroUbicaciónDescripción
organization_idqueryEmpresa autorizada.
farm_idqueryFinca a la que pertenecen los lotes.
limitqueryCantidad entre 1 y 100.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

curl "${HARVIS_API_URL}/v1/plots?farm_id=${FARM_ID}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "id": "lote-uuid", "farm_id": "finca-uuid", "name": "Lote Norte" }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}
GET/v1/crops

Listar cultivos

Consulta cultivos y variedades de empresas autorizadas.

Scope requeridocrops:read
ParámetroUbicaciónDescripción
organization_idqueryEmpresa autorizada.
limitqueryCantidad entre 1 y 100.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# organization_id: ID del productor asociado retornado por GET /v1/associated-producers
export ORGANIZATION_ID="uuid-del-productor-asociado"

curl "${HARVIS_API_URL}/v1/crops?organization_id=${ORGANIZATION_ID}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "id": "cultivo-uuid", "name": "Café", "varieties": ["Castillo"] }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}
GET/v1/field-records

Listar registros de campo

Incluye finca, lotes y el mensaje fuente únicamente cuando pertenece a la empresa autorizada.

Scope requeridofield_records:read
ParámetroUbicaciónDescripción
organization_idqueryEmpresa autorizada.
farm_idqueryFinca del registro.
fromqueryFecha inicial YYYY-MM-DD.
toqueryFecha final YYYY-MM-DD.
typequeryTipo de registro.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

curl "${HARVIS_API_URL}/v1/field-records?farm_id=${FARM_ID}&from=2026-10-01" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{
    "id": "registro-uuid",
    "farm_id": "finca-uuid",
    "plot_ids": ["lote-uuid"],
    "recorded_by": { "id": "usuario-uuid", "name": "María Pérez", "phone_number": 573001234567 },
    "source_message": { "type": "text", "content": { "body": "Aplicación realizada" } }
  }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}

Clima y alertas

Datos anidados por finca. Las observaciones de v1 excluyen pronósticos.

GET/v1/farms/{farmId}/climate/observations

Consultar clima observado

Retorna únicamente datos historical_day y current.

Scope requeridoclimate:read
ParámetroUbicaciónDescripción
farmId*pathID de finca autorizada.
fromqueryFecha inicial YYYY-MM-DD.
toqueryFecha final YYYY-MM-DD.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

curl "${HARVIS_API_URL}/v1/farms/${FARM_ID}/climate/observations?from=2026-10-01" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "valid_date": "2026-10-01", "temperature_c": 19, "precipitation_mm": 5 }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}
GET/v1/farms/{farmId}/climate/alerts

Consultar alertas climáticas

Incluye nivel, mensaje y acción recomendada en campo.

Scope requeridoalerts:read
ParámetroUbicaciónDescripción
farmId*pathID de finca autorizada.
fromqueryFecha inicial YYYY-MM-DD.
toqueryFecha final YYYY-MM-DD.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

# farmId: ID de la finca retornado por GET /v1/farms
export FARM_ID="uuid-de-la-finca"

curl "${HARVIS_API_URL}/v1/farms/${FARM_ID}/climate/alerts" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "level": "alta", "type": "lluvia", "field_action": "Reprogramar aplicación" }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}

Pedidos y productos

Pedidos y catálogo aislados por canal autorizado.

GET/v1/orders

Listar pedidos

Solo retorna pedidos que tengan un canal perteneciente a una empresa autorizada.

Scope requeridoorders:read
ParámetroUbicaciónDescripción
organization_idqueryEmpresa autorizada.
channelqueryCanal autorizado.
limitqueryCantidad entre 1 y 100.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# channel: nombre del canal autorizado de la empresa
export CHANNEL="nombre-del-canal"

curl "${HARVIS_API_URL}/v1/orders?channel=${CHANNEL}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{
    "id": "pedido-uuid",
    "channel": "canal_empresa",
    "status": "pendiente",
    "requested_by": { "id": "usuario-uuid", "name": "María Pérez", "phone_number": 573001234567 },
    "item_count": 2
  }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}
GET/v1/orders/{orderId}

Obtener pedido

Retorna el detalle del pedido e ítems de inventario que pertenezcan al canal.

Scope requeridoorders:read
ParámetroUbicaciónDescripción
orderId*pathID de pedido autorizado.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# orderId: ID del pedido retornado por GET /v1/orders
export ORDER_ID="uuid-del-pedido"

curl "${HARVIS_API_URL}/v1/orders/${ORDER_ID}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": {
    "id": "pedido-uuid",
    "requested_by": { "id": "usuario-uuid", "name": "María Pérez", "phone_number": 573001234567 },
    "items": [{ "product": { "name": "Fertilizante A" } }]
  },
  "request_id": "req_01H..."
}
GET/v1/products

Listar productos

El parámetro channel es obligatorio.

Scope requeridoproducts:read
ParámetroUbicaciónDescripción
channel*queryCanal autorizado.
organization_idqueryEmpresa autorizada.
limitqueryCantidad entre 1 y 100.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# channel: nombre del canal autorizado de la empresa
export CHANNEL="nombre-del-canal"

curl "${HARVIS_API_URL}/v1/products?channel=${CHANNEL}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}"
application/json
{
  "data": [{ "id": "producto-uuid", "name": "Fertilizante A", "active": true }],
  "page": { "next_cursor": null },
  "request_id": "req_01H..."
}
POST/v1/products

Crear producto

Crea un producto y deriva su empresa desde el canal.

Scope requeridoproducts:write
ParámetroUbicaciónDescripción
Idempotency-Key*headerIdentificador único del intento de escritura.
channel*bodyCanal autorizado.
name*bodyNombre del producto.
code, linebodyOpcionales. Código único por canal y línea/categoría comercial.
base_price, currencybodyOpcionales. Monto no negativo; currency acepta COP o USD.
taxes, discountsbodyOpcionales. Arreglos de { name, percentage }. Cada percentage debe ser ≥ 0.
description, summary_descriptionbodyOpcionales. Texto largo y resumen comercial.
keywords, conversational_variantsbodyOpcionales. Arreglos de texto para búsqueda y canal conversacional.
final_pricerespuestaSolo servidor. Se calcula como base_price × (1 + impuestos) × (1 - descuentos).
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# channel: nombre del canal autorizado de la empresa
export CHANNEL="nombre-del-canal"

curl -X POST "${HARVIS_API_URL}/v1/products" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}" \
  -H "Idempotency-Key: producto-erp-0001" \
  -H "Content-Type: application/json" \
  -d '{"channel":"canal_empresa","code":"FERT-01","line":"agricultura","name":"Fertilizante A","description":"Fertilizante de aplicación foliar.","summary_description":"Aplicación foliar","base_price":120000,"currency":"COP","taxes":[{"name":"iva","percentage":5}],"discounts":[{"name":"lanzamiento","percentage":10}],"keywords":["fertilizante","foliar"],"conversational_variants":["fertilizante A"]}'
application/json
{
  "data": {
    "id": "producto-uuid",
    "organization_id": "empresa-uuid",
    "channel": "canal_empresa",
    "code": "FERT-01",
    "line": "agricultura",
    "name": "Fertilizante A",
    "active": true,
    "base_price": 120000,
    "currency": "COP",
    "taxes": [{ "name": "iva", "percentage": 5 }],
    "discounts": [{ "name": "lanzamiento", "percentage": 10 }],
    "final_price": 113400,
    "description": "Fertilizante de aplicación foliar.",
    "summary_description": "Aplicación foliar",
    "keywords": ["fertilizante", "foliar"],
    "conversational_variants": ["fertilizante A"],
    "created_at": "2026-10-29T00:00:00.000Z",
    "updated_at": "2026-10-29T00:00:00.000Z"
  },
  "request_id": "req_01H..."
}

No envíe empresa_id ni final_price. La API deriva la empresa desde el canal y calcula final_price aplicando impuestos y después descuentos.

PATCH/v1/products/{productId}

Editar producto

Edita campos permitidos sin mover el producto a otro canal.

Scope requeridoproducts:write
ParámetroUbicaciónDescripción
productId*pathID de producto autorizado.
Idempotency-Key*headerIdentificador único del intento de escritura.
code, line, namebodyOpcionales. Identidad comercial.
base_price, currencybodyOpcionales. Precio base y moneda.
taxes, discountsbodyOpcionales. Arreglos de { name, percentage }; recalculan final_price.
description, summary_descriptionbodyOpcionales. Contenido comercial.
keywords, conversational_variantsbodyOpcionales. Arreglos de texto.
final_pricerespuestaSolo servidor. Devuelve el precio recalculado completo.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# productId: ID del producto retornado por GET /v1/products
export PRODUCT_ID="uuid-del-producto"

curl -X PATCH "${HARVIS_API_URL}/v1/products/${PRODUCT_ID}" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}" \
  -H "Idempotency-Key: producto-erp-0002" \
  -H "Content-Type: application/json" \
  -d '{"name":"Fertilizante A Plus"}'
application/json
{
  "data": { "id": "producto-uuid", "name": "Fertilizante A Plus" },
  "request_id": "req_01H..."
}
POST/v1/products/{productId}/activate

Activar producto

Habilita un producto existente.

Scope requeridoproducts:write
ParámetroUbicaciónDescripción
productId*pathID de producto autorizado.
Idempotency-Key*headerIdentificador único del intento.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# productId: ID del producto retornado por GET /v1/products
export PRODUCT_ID="uuid-del-producto"

curl -X POST "${HARVIS_API_URL}/v1/products/${PRODUCT_ID}/activate" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}" \
  -H "Idempotency-Key: producto-erp-0003"
application/json
{
  "data": { "id": "producto-uuid", "active": true },
  "request_id": "req_01H..."
}
POST/v1/products/{productId}/deactivate

Desactivar producto

Deshabilita un producto sin eliminar su historial.

Scope requeridoproducts:write
ParámetroUbicaciónDescripción
productId*pathID de producto autorizado.
Idempotency-Key*headerIdentificador único del intento.
··
cURL
# Variables requeridas
export HARVIS_API_URL="https://api.harvis.app"
export HARVIS_API_KEY="hv_live_tu_clave_secreta"

# productId: ID del producto retornado por GET /v1/products
export PRODUCT_ID="uuid-del-producto"

curl -X POST "${HARVIS_API_URL}/v1/products/${PRODUCT_ID}/deactivate" \
  -H "Authorization: Bearer ${HARVIS_API_KEY}" \
  -H "Idempotency-Key: producto-erp-0004"
application/json
{
  "data": { "id": "producto-uuid", "active": false },
  "request_id": "req_01H..."
}

Webhooks

Use webhooks para recibir eventos de registros de campo en tiempo real. El receptor debe responder 2xx rápido e implementar idempotencia para reintentos.

Ver guía de webhooks

Changelog

v1 · Lanzamiento inicial

Organización, productores, estructura productiva, registros, clima, pedidos, contactos y productos por canal.

OpenAPI Reference

El contrato versionado openapi.yaml es la fuente de verdad de rutas, parámetros y esquemas. Se publica desde la propia API junto con cada despliegue.

Abrir contrato OpenAPI