Hablar por WhatsApp
Integraciones

API de integraciones de Plusdiario

Conectá tu sistema con contactos, prospectos, productos, stock, presupuestos, pedidos, ventas, cobros y facturación. Cada operación declara sus efectos y conserva su trazabilidad.

Empezar a integrar
Activación de v2. Requiere instalar la migración y habilitar permisos para el token desde Control de Empresa. Un token v1 no obtiene accesos nuevos automáticamente. Si recibís 503 api_not_installed, la instalación está pendiente; el endpoint v1 sigue disponible.
Empezá por acá

Tu primera integración

  1. En el CRM abrí Control de Empresa → API de Ingesta de Leads Externos y generá un token. Copialo: se muestra completo una sola vez.
  2. En Permisos de la API comercial v2, seleccioná el token, su usuario operativo y los permisos necesarios. Para este ejemplo: contactos:read y contactos:write.
  3. Enviá solicitudes desde tu servidor con Authorization: Bearer TU_TOKEN_API. Nunca pongas el token en JavaScript del navegador, URLs ni repositorios.
  4. Elegí una Idempotency-Key estable para cada operación. Guardala y reutilizala si se corta la conexión.
cURL
curl --request POST 'https://www.plusdiario.com.ar/api/v2/contactos.php' \
  --header 'Authorization: Bearer TU_TOKEN_API' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: contacto-web-123' \
  --data '{"external_id":"cliente-123","nombre":"Ana Ejemplo","telefono":"1112345678"}'

La respuesta contiene data.id y data.version. Los IDs son de ejemplo: consultá los reales y enviá identificadores como texto.

Respuesta v2
{
  "status": "ok",
  "data": {"id": "123", "nombre": "Ana Ejemplo", "scoring": 0, "version": "..."},
  "error": null,
  "meta": {"request_id": "...", "version": "2", "replayed": false}
}

El ejemplo abrevia los campos de data. La documentación no ejecuta operaciones contra tu empresa.

De dónde vienen los clics de WhatsApp

Desde Control de Empresa → Origen de los clics de WhatsApp, agregá tu sitio y sus dominios HTTPS exactos. Incluí por separado la dirección con y sin www si usás ambas. Copiá el código que aparece allí e instalalo antes de </body> en cada página pública.

Script de medición (ID de ejemplo)
<script defer src="https://www.plusdiario.com.ar/js/pd-web-attribution.js" data-site="00000000000000000000000000000000"></script>

Usá el código real del panel. Su atributo data-site es un identificador público de medición; nunca debe contener el token de la API comercial. La medición no crea leads, no altera los enlaces ni agrega referencias al mensaje.

  • Origen: etiquetas utm_source, utm_medium y utm_campaign, señales de clic de Google o Meta, y dominio de referencia disponible. Ejemplo: https://tuweb.com/producto?utm_source=instagram&utm_medium=social&utm_campaign=lanzamiento.
  • Sesión: se conserva en la pestaña durante 30 minutos de inactividad. El primer origen se mantiene al navegar; un nuevo origen explícito también queda registrado. Pestañas y navegadores diferentes pueden representar sesiones distintas.
  • Clic: se detectan enlaces a wa.me, api.whatsapp.com, web.whatsapp.com, www.whatsapp.com y whatsapp:, incluso si aparecen después por AJAX. Podés identificar un botón con data-placement="producto" o excluir un área con data-pd-tracking="off".
  • Lectura del informe: un clic no demuestra que se envió un mensaje. fbclid solo no distingue Facebook de Instagram ni demuestra tráfico pago. Si falta información se informa Directo / no identificado.
  • Almacenamiento: se conservan 90 días de eventos; se omiten query strings completas, fragmentos, contenido de mensajes, teléfonos de destino e IP sin procesar. La protección contra abuso usa un hash temporal de IP con sal privada. El identificador del navegador no se vincula automáticamente con personas del CRM.

Para esperar el consentimiento de tu web, agregá data-consent="required" al script y llamá window.PlusdiarioTracking?.setConsent(true) después de obtenerlo; setConsent(false) detiene la medición y borra el estado local. Se respetan Do Not Track y Global Privacy Control. En una web con navegación sin recarga, llamá window.PlusdiarioTracking?.trackPage() tras cambiar de página.

La medición pública valida los dominios habilitados y limita el tráfico, pero las etiquetas son datos declarados por el navegador. No sirven como prueba de identidad, pago o venta. Los bloqueadores, restricciones del navegador y la falta de consentimiento pueden reducir los conteos.

Qué representa cada operación

Contacto

Una persona o cliente. Su alta no inventa una consulta ni confirma una venta.

Lead

Una consulta comercial con mensaje, origen y seguimiento. Comparte la identidad del CRM.

Presupuesto

Una propuesta con artículos e importes; todavía no implica venta, entrega ni cobro.

Pedido

La organización de la preparación y entrega. Su estado de cobro se mantiene separado.

Venta

Una operación confirmada; el prospecto queda con scoring 20. El buzón Ventas no indica una venta cerrada.

Cobro

Un pago efectivamente recibido. Reduce el saldo y genera ingreso de caja y recibo interno.

Recibo

Constancia interna de un cobro registrado. No equivale a una factura fiscal.

Factura y nota de crédito

Comprobantes autorizados por ARCA. Tienen estado independiente de venta y cobro.

Reglas comunes

  • Base: https://www.plusdiario.com.ar/api/v2/. Solicitudes JSON de hasta 2 MiB.
  • Permisos: recurso:read para GET y recurso:write para POST/PATCH. También se verifican el usuario operativo, sus módulos y su visibilidad del CRM. La empresa sale del token.
  • Moneda y precisión: nuevas operaciones en ARS. Dinero y cantidades usan punto decimal, sin miles, hasta 2 decimales; enviarlos como texto evita pérdida de precisión. El límite de importes y cantidades individuales es 9.999.999,99. stock_minimo conserva los 3 decimales de su ficha.
  • Idempotencia: toda escritura requiere Idempotency-Key de 8 a 190 caracteres: letras, números, _ . : -. Misma clave y mismo contenido devuelven el resultado anterior; otro contenido produce 409. Las claves y referencias se conservan para proteger reintentos históricos.
  • Identidad externa: external_id se vincula por empresa, token y recurso. Si repetís una referencia ya creada se devuelve el registro original; para modificarlo usá PATCH. Si los datos de contacto coinciden con otros registros, se devuelve un conflicto para evitar fusiones incorrectas.
  • Edición: consultá el registro por GET y enviá su version en PATCH o transiciones. No se borran operaciones confirmadas; las correcciones se registran con trazabilidad.
  • Páginas: las colecciones paginadas devuelven items y next_after. Enviá ese cursor en after; limit vale 50 de forma predeterminada y admite hasta 100. Usá webhooks para cambios sobre registros ya leídos.
  • Límite por minuto: se configura por token, entre 10 y 1.000 solicitudes, inicialmente 120. Respetá X-RateLimit-Remaining y Retry-After.
Efectos explícitos. Una venta externa no descuenta stock ni crea cobros. Una venta operativa exige afectar_stock y pagos; [] mantiene el saldo pendiente. Afectar stock requiere stock:write; registrar pagos o reintegros requiere cobros:write. Facturar siempre se solicita por separado.

Referencia por endpoint

GET consulta; POST crea o ejecuta acciones; PATCH actualiza campos editables. El campo id se envía en la URL para consultar un registro, editarlo o cambiar su estado.

contactos.phpGET POST PATCH

Contacto sin consulta ni venta implícita.

Permisos: contactos:read y contactos:write.

Ejemplo JSON
{
    "nombre": "Ana Ejemplo",
    "telefono": "1112345678",
    "external_id": "cliente-123"
}
CampoTipoUso
nombrestringNombre. Obligatorio al crear un contacto, lead o producto.
apellidostringapellido.
telefonostringTeléfono como texto, de 7 a 15 dígitos; se permiten signos de formato. No enviar como número JSON.
emailstringCorreo electrónico válido.
dnistringDNI de 7 u 8 dígitos.
cuitstringCUIT de 11 dígitos.
direccionstringdireccion.
ciudadstringciudad.
provinciastringprovincia.
paisstringpais.
cpstringcp.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.
estado_idIDIdentificador obtenido desde esta API o catalogos.php.
responsable_idIDIdentificador obtenido desde esta API o catalogos.php.
sourcestringOrigen del registro. Ejemplo: web_form, ecommerce o sistema_gestion.
source_detailstringsource detail.
metadataobjectObjeto con UTMs u otros datos auxiliares, hasta 16 KB. No enviar secretos.
ad_account_idstringad account id.
ad_idstringad id.
campaign_idstringcampaign id.
adgroup_idstringadgroup id.
ad_namestringad name.
adset_namestringadset name.
campaign_namestringcampaign name.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

leads.phpGET POST PATCH

Consulta comercial vinculada al CRM. El estado de venta requiere permiso ventas:write.

Permisos: leads:read y leads:write.

Ejemplo JSON
{
    "nombre": "Ana Ejemplo",
    "telefono": "1112345678",
    "mensaje": "Quiero información",
    "source": "web_form",
    "external_id": "lead-123"
}
CampoTipoUso
nombrestringNombre. Obligatorio al crear un contacto, lead o producto.
apellidostringapellido.
telefonostringTeléfono como texto, de 7 a 15 dígitos; se permiten signos de formato. No enviar como número JSON.
emailstringCorreo electrónico válido.
dnistringDNI de 7 u 8 dígitos.
cuitstringCUIT de 11 dígitos.
direccionstringdireccion.
ciudadstringciudad.
provinciastringprovincia.
paisstringpais.
cpstringcp.
mensajestringTexto de la consulta; obligatorio al crear un lead.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.
estado_idIDIdentificador obtenido desde esta API o catalogos.php.
responsable_idIDIdentificador obtenido desde esta API o catalogos.php.
sourcestringOrigen del registro. Ejemplo: web_form, ecommerce o sistema_gestion.
source_detailstringsource detail.
metadataobjectObjeto con UTMs u otros datos auxiliares, hasta 16 KB. No enviar secretos.
ad_account_idstringad account id.
ad_idstringad id.
campaign_idstringcampaign id.
adgroup_idstringadgroup id.
ad_namestringad name.
adset_namestringadset name.
campaign_namestringcampaign name.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

productos.phpGET POST PATCH

Catálogo compartido con inventario. El stock se modifica exclusivamente en stock.php.

Permisos: productos:read y productos:write.

Ejemplo JSON
{
    "codigo": "SKU-123",
    "nombre": "Producto de ejemplo",
    "precio_venta": "100.00",
    "controlar_stock": true
}
CampoTipoUso
nombrestringNombre. Obligatorio al crear un contacto, lead o producto.
codigostringcodigo.
marcastringmarca.
familiastringfamilia.
lineastringlinea.
descripcionstringdescripcion.
unidadstringunidad.
codigo_mlstringcodigo ml.
catalog_product_idstringcatalog product id.
foto_urlstringLa validación de ficha existente admite imágenes HTTPS de mlstatic.com. No se descargan imágenes arbitrarias.
costostringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_ventastringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_mayoristastringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_3_cuotasstringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_6_cuotasstringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_9_cuotasstringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
precio_12_cuotasstringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
controlar_stockbooleancontrolar stock.
visible_chatbooleanvisible chat.
stock_minimostringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
proveedor_idIDIdentificador obtenido desde esta API o catalogos.php.
tipostringTipo de producto simple/compuesto/insumo, o clase fiscal A/B/C según el recurso. Valores: simple, compuesto, insumo.
componentesarrayComposición de un producto compuesto: inventario_id y cantidad por componente. Se rechazan ciclos y referencias ajenas.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

stock.phpGET POST

Entradas, salidas, ajustes y Kardex. Lectura por inventario_id. Para crear lote: codigo_lote y fecha_vencimiento opcional.

Permisos: stock:read y stock:write.

Ejemplo JSON
{
    "inventario_id": "10",
    "action": "entrada",
    "cantidad": "10.00",
    "motivo": "Recepción de mercadería",
    "external_id": "recepcion-123"
}
CampoTipoUso
inventario_idIDIdentificador obtenido desde esta API o catalogos.php.
actionstringaction. Valores: entrada, salida, ajuste.
cantidadstringCantidad positiva con hasta 2 decimales. En un ajuste representa el nuevo stock absoluto y admite cero.
stock_esperadostringStock leído previamente, obligatorio para ajustes; si cambió se responde 409.
motivostringExplicación obligatoria del movimiento o devolución, hasta 500 caracteres.
lote_idIDIdentificador obtenido desde esta API o catalogos.php.
codigo_lotestringcodigo lote.
fecha_vencimientostringfecha vencimiento.
venta_idIDIdentificador obtenido desde esta API o catalogos.php.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

presupuestos.phpGET POST PATCH

Presupuestos al contado en ARS, editables antes de convertirlos. Financiación histórica se conserva en su circuito actual.

Permisos: presupuestos:read y presupuestos:write.

Ejemplo JSON
{
    "cliente_id": "123",
    "items": [
        {
            "inventario_id": "10",
            "cantidad": "2.00"
        }
    ],
    "observaciones": "Presupuesto de ejemplo"
}
CampoTipoUso
cliente_idIDIdentificador obtenido desde esta API o catalogos.php.
itemsarrayArtículos. Se calcula el total en el servidor; precio_unitario omitido usa el catálogo. Sin inventario_id, articulo y precio_unitario son obligatorios.
monedastringARS para operaciones nuevas. Los históricos se consultan en su moneda original. Valores: ARS.
observacionesstringobservaciones.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.
actionstringaction. Valores: convertir_pedido, convertir_venta.
afectar_stockbooleanBooleano obligatorio para venta operativa o su conversión; requiere stock:write cuando es true.
pagosarrayPagos realmente recibidos. Lista obligatoria en venta operativa; [] deja el saldo pendiente. Cada pago usa monto, metodo_pago y sucursal_id opcional.
sucursal_idstringsucursal id.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

pedidos.phpGET POST PATCH

Preparación y entrega con venta, stock y cobro explícitos. Una entrega sin pagos conserva saldo pendiente.

Permisos: pedidos:read y pedidos:write.

Ejemplo JSON
{
    "cliente_id": "123",
    "items": [
        {
            "inventario_id": "10",
            "cantidad": "2.00"
        }
    ],
    "direccion_entrega": "Dirección de ejemplo",
    "ciudad_entrega": "Ciudad"
}
CampoTipoUso
cliente_idIDIdentificador obtenido desde esta API o catalogos.php.
presupuesto_idIDIdentificador obtenido desde esta API o catalogos.php.
itemsarrayArtículos. Se calcula el total en el servidor; precio_unitario omitido usa el catálogo. Sin inventario_id, articulo y precio_unitario son obligatorios.
monedastringARS para operaciones nuevas. Los históricos se consultan en su moneda original. Valores: ARS.
direccion_entregastringdireccion entrega.
ciudad_entregastringciudad entrega.
notasstringnotas.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.
actionstringaction. Valores: confirmar, preparar, despachar, entregar, cancelar, confirmar_venta.
afectar_stockbooleanBooleano obligatorio para venta operativa o su conversión; requiere stock:write cuando es true.
pagosarrayPagos realmente recibidos. Lista obligatoria en venta operativa; [] deja el saldo pendiente. Cada pago usa monto, metodo_pago y sucursal_id opcional.
sucursal_idstringsucursal id.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

ventas.phpGET POST

Modo externa importa la venta sin efectos adicionales. Modo operativa exige afectar_stock y pagos (incluido []). Registra scoring 20.

Permisos: ventas:read y ventas:write.

Ejemplo JSON
{
    "modo": "operativa",
    "cliente_id": "123",
    "items": [
        {
            "inventario_id": "10",
            "cantidad": "2.00"
        }
    ],
    "afectar_stock": true,
    "pagos": [],
    "sucursal_id": "1",
    "external_id": "venta-123"
}
CampoTipoUso
modostringexterna u operativa. No hay un modo predeterminado. Valores: externa, operativa.
cliente_idIDIdentificador obtenido desde esta API o catalogos.php.
presupuesto_idIDIdentificador obtenido desde esta API o catalogos.php.
pedido_idIDIdentificador obtenido desde esta API o catalogos.php.
itemsarrayArtículos. Se calcula el total en el servidor; precio_unitario omitido usa el catálogo. Sin inventario_id, articulo y precio_unitario son obligatorios.
monedastringARS para operaciones nuevas. Los históricos se consultan en su moneda original. Valores: ARS.
afectar_stockbooleanBooleano obligatorio para venta operativa o su conversión; requiere stock:write cuando es true.
pagosarrayPagos realmente recibidos. Lista obligatoria en venta operativa; [] deja el saldo pendiente. Cada pago usa monto, metodo_pago y sucursal_id opcional.
sucursal_idstringsucursal id.
fechastringfecha.
observacionesstringobservaciones.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

cobros.phpGET POST

Registrar un ingreso real y su recibo interno. Lectura por venta_id. No ejecuta transferencias ni pasarelas.

Permisos: cobros:read y cobros:write.

Ejemplo JSON
{
    "venta_id": "456",
    "monto": "100.00",
    "metodo_pago": "transferencia",
    "sucursal_id": "1",
    "external_id": "pago-123"
}
CampoTipoUso
venta_idIDIdentificador obtenido desde esta API o catalogos.php.
montostringDecimal con punto, sin separador de miles. Enviar como texto para conservar precisión.
metodo_pagostringefectivo, transferencia, tarjeta, mercadopago, cheque u otro. Valores: efectivo, transferencia, tarjeta, mercadopago, cheque, otro.
sucursal_idstringsucursal id.
monedastringARS para operaciones nuevas. Los históricos se consultan en su moneda original. Valores: ARS.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

devoluciones.phpGET POST

Devoluciones de artículos con detalle trazable v2; reposición y reintegro explícitos. Las operaciones históricas sin ese detalle requieren revisión en su circuito original.

Permisos: devoluciones:read y devoluciones:write.

Ejemplo JSON
{
    "venta_id": "456",
    "items": [
        {
            "sale_item_id": "789",
            "cantidad": "1.00"
        }
    ],
    "motivo": "Devolución acordada",
    "reponer_stock": true,
    "reintegro": "0.00",
    "external_id": "devolucion-123"
}
CampoTipoUso
venta_idIDIdentificador obtenido desde esta API o catalogos.php.
itemsarrayArtículos. Se calcula el total en el servidor; precio_unitario omitido usa el catálogo. Sin inventario_id, articulo y precio_unitario son obligatorios.
motivostringExplicación obligatoria del movimiento o devolución, hasta 500 caracteres.
reponer_stockbooleanBooleano obligatorio en devoluciones. true repone los productos/componentes y lotes descontados originalmente.
reintegrostringImporte efectivamente reintegrado. Obligatorio incluso cuando es 0.00; mayor a cero requiere cobros:write y metodo_pago.
metodo_pagostringefectivo, transferencia, tarjeta, mercadopago, cheque u otro. Valores: efectivo, transferencia, tarjeta, mercadopago, cheque, otro.
sucursal_idstringsucursal id.
monedastringARS para operaciones nuevas. Los históricos se consultan en su moneda original. Valores: ARS.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

comprobantes.phpGET POST

Facturas A/B/C y notas de crédito asociadas, asíncronas. Consultar por venta_id, id de comprobante o job_id. Una alícuota explícita por comprobante A/B (10.5, 21 o 27).

Permisos: comprobantes:read y comprobantes:write.

Ejemplo JSON
{
    "action": "factura",
    "venta_id": "456",
    "tipo": "C",
    "condicion_iva": "Consumidor Final",
    "concepto_arca": 1,
    "external_id": "factura-123"
}
CampoTipoUso
actionstringaction. Valores: factura, nota_credito, reintentar.
venta_idIDIdentificador obtenido desde esta API o catalogos.php.
devolucion_idIDIdentificador obtenido desde esta API o catalogos.php.
tipostringTipo de producto simple/compuesto/insumo, o clase fiscal A/B/C según el recurso. Valores: A, B, C.
concepto_arcaID1 productos, 2 servicios, 3 ambos. Servicios requieren fecha_desde, fecha_hasta y fecha_vto_pago.
conceptostringconcepto.
doc_tipoID80 CUIT, 96 DNI, 99 consumidor final.
doc_nrostringDocumento fiscal como texto; 0 para tipo 99.
nombrestringNombre. Obligatorio al crear un contacto, lead o producto.
condicion_ivastringCondición fiscal del receptor: responsable inscripto, monotributista, exento o consumidor final.
iva_alicuotastringAlícuota explícita para A/B: 10.5, 21 o 27. La nota de crédito conserva la de la factura original.
fecha_desdestringfecha desde.
fecha_hastastringfecha hasta.
fecha_vto_pagostringfecha vto pago.
job_idIDIdentificador obtenido desde esta API o catalogos.php.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 202 con job_id al crear; consultá el estado hasta done, failed, rejected o uncertain. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

catalogos.phpGET

Referencias de la empresa: estados, responsables autorizados, sucursales, medios de pago, monedas y permisos efectivos.

Permisos: catalogos:read.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

lotes.phpGET POST

Importaciones de 1 a 100 operaciones homogéneas. Cada elemento se confirma por separado. Consultar id/job_id y reintentar solo fallidos.

Permisos: lotes:read y lotes:write.

Ejemplo JSON
{
    "recurso": "contactos",
    "metodo": "POST",
    "items": [
        {
            "data": {
                "nombre": "Ana Ejemplo",
                "telefono": "1112345678"
            }
        }
    ],
    "external_id": "importacion-123"
}
CampoTipoUso
recursostringrecurso.
metodostringmetodo.
itemsarrayArtículos. Se calcula el total en el servidor; precio_unitario omitido usa el catálogo. Sin inventario_id, articulo y precio_unitario son obligatorios.
actionstringaction. Valores: reintentar.
job_idIDIdentificador obtenido desde esta API o catalogos.php.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 202 con job_id al crear; consultá el estado hasta done, failed, rejected o uncertain. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

webhooks.phpGET POST PATCH

Suscripciones por integración con firma HMAC. Su administración requiere rango 90 o superior. GET action=entregas&id=WEBHOOK_ID lista entregas; delivery_id consulta una entrega.

Permisos: webhooks:read y webhooks:write.

Ejemplo JSON
{
    "url": "https://integracion.example.com/webhooks/plusdiario",
    "topics": [
        "ventas.created",
        "stock.created"
    ],
    "enabled": true
}
CampoTipoUso
urlstringDestino HTTPS público con puerto 443. No admite credenciales, destinos internos ni redirecciones.
topicsarrayLista de eventos exactos; exige permiso de lectura de los recursos correspondientes.
enabledbooleanenabled.
versionstringValor devuelto al consultar el registro. Obligatorio al editar y al ejecutar transiciones de documentos; evita sobrescribir cambios concurrentes.
actionstringaction. Valores: reenviar.
delivery_idIDIdentificador obtenido desde esta API o catalogos.php.
external_idstringReferencia estable del sistema externo. Única por empresa, token y recurso; repetirla devuelve el registro vinculado. Hasta 190 caracteres.

Resultado: 200 al consultar o editar; 201 al crear. data devuelve el registro, sus identificadores y el estado resultante. Errores: 401/403 acceso, 404 registro no disponible, 409 conflicto y 422 datos inválidos.

Campos obligatorios según operación

  • Contacto: nombre. Lead: nombre y mensaje. Teléfono, email y documentos ayudan a detectar conflictos.
  • Producto: nombre y codigo; comienza con stock cero. Stock: inventario_id, action, cantidad y motivo; ajuste exige stock_esperado. Productos con lotes requieren un lote para ingresos; sus salidas usan lotes disponibles por vencimiento. Los ajustes de compuestos se realizan sobre sus componentes.
  • Presupuesto/pedido: cliente_id e items, o presupuesto_id para crear un pedido desde uno existente. Los artículos usan cantidad y un inventario_id; si no están en catálogo necesitan articulo y precio_unitario.
  • Venta: modo, sucursal_id y cliente_id con items, o un presupuesto_id/pedido_id válido que provea cliente y artículos. El modo operativa exige afectar_stock y pagos. Si afecta stock, todos los artículos necesitan inventario_id.
  • Cobro: venta_id, monto y metodo_pago. Devolución: venta_id, items con sale_item_id y cantidad, motivo, reponer_stock y reintegro (incluso 0.00).
  • Factura: venta_id, tipo y condicion_iva; para A/B, iva_alicuota. El documento se toma del contacto o de doc_tipo/doc_nro explícitos. Para servicios se exigen sus tres fechas.
  • Nota de crédito: action=nota_credito, venta_id y devolucion_id; toma clase, receptor y alícuota de la factura autorizada.

Recorridos completos

Del contacto a la factura

  1. Creá o consultá el contacto y guardá su ID.
  2. Consultá productos y sucursales, creá el presupuesto y guardá su ID y version.
  3. En presupuestos.php?id=ID enviá {"action":"convertir_pedido","version":"..."}.
  4. En pedidos.php?id=ID avanzá con confirmar, preparar y despachar cuando corresponda. Cada acción devuelve una nueva version.
  5. Para entregar enviá {"action":"entregar","version":"...","afectar_stock":true,"pagos":[],"sucursal_id":"1"}. Se confirma la venta y entrega sin inventar un cobro.
  6. Cuando recibas el pago, registralo en cobros.php; conservá el recibo y consultá el saldo.
  7. Solicitá la factura en comprobantes.php y consultá ?job_id=ID. Solo done con comprobante autorizado permite mostrar la factura como emitida.

Importar una venta realizada en otro sistema

Usá modo externa, una referencia comercial estable y los artículos/importes originales. Se crea la venta y se aplica scoring 20; stock, pagos y factura permanecen separados. Si necesitás reflejar movimientos reales adicionales, registralos explícitamente y vinculalos con venta_id.

Devolución parcial

Consultá la venta para obtener items[].id. Enviá ese valor como sale_item_id, la cantidad devuelta y si debe reponerse. Informá el reintegro efectivamente realizado; no se ejecuta una transferencia. Si la venta fue facturada, solicitá después su nota de crédito con devolucion_id. La venta original y su scoring se conservan.

Actualizar sin perder cambios

Hacé GET, tomá version y enviá PATCH con solo los campos que quieras cambiar. Ante 409, volvé a consultar y revisá el conflicto; una corrección del contenido necesita una nueva Idempotency-Key.

PHP, JavaScript de servidor, n8n y Make

PHP de servidor
$body = json_encode(['external_id'=>'cliente-123','nombre'=>'Ana Ejemplo','telefono'=>'1112345678']);
$curl = curl_init('https://www.plusdiario.com.ar/api/v2/contactos.php');
curl_setopt_array($curl, [
    CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>$body, CURLOPT_RETURNTRANSFER=>true,
    CURLOPT_TIMEOUT=>30,
    CURLOPT_HTTPHEADER=>['Content-Type: application/json',
        'Authorization: Bearer '.getenv('PLUSDIARIO_API_TOKEN'),
        'Idempotency-Key: contacto-web-123']
]);
$response = curl_exec($curl);
$httpStatus = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
// Evaluá httpStatus y error.code. Conservá la misma clave en reintentos.
JavaScript de servidor
const response = await fetch('https://www.plusdiario.com.ar/api/v2/contactos.php', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.PLUSDIARIO_API_TOKEN}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'contacto-web-123'
  },
  body: JSON.stringify({ external_id: 'cliente-123', nombre: 'Ana Ejemplo', telefono: '1112345678' })
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
// Persistí result.data.id para vincular las operaciones siguientes.
  • n8n: usá HTTP Request, autenticación por header Bearer y cuerpo JSON. Derivá Idempotency-Key del ID estable del evento de origen. Guardá data.id; para trabajos asíncronos consultá job_id hasta un estado final. Ramificá errores por código.
  • Make: usá HTTP → Make a request con los mismos headers. Guardá el token en una conexión privada y los IDs en tu almacenamiento. No generes una clave nueva en cada reintento del mismo evento.
  • Lotes: POST a lotes.php con recurso, metodo e items de la forma {"query":{"id":"123"},"data":{...}}. Los elementos son independientes; creá primero los registros de los que dependen otros lotes. Consultá cada resultado y usá action=reintentar para fallidos. Los elementos exitosos no se ejecutan nuevamente.

Recibir cambios mediante webhooks

Registrá un destino HTTPS y topics exactos en webhooks.php. Guardá el secret de la respuesta de creación de forma privada. La suscripción comienza con los eventos posteriores a su alta y respeta los permisos actuales del token y del usuario.

Evento y verificación
X-PD-Event-ID: 123
X-PD-Timestamp: 1793050000
X-PD-Signature: v1=FIRMA_HEXADECIMAL

{"id":"123","type":"ventas.created","occurred_at":"2026-10-26T12:00:00-03:00","data":{"id":"456"}}

Firma esperada: HMAC-SHA256(secret, timestamp + "." + cuerpo_original)

Verificá la firma sobre el cuerpo recibido sin modificarlo, comparala en tiempo constante y rechazá timestamps con más de 5 minutos de diferencia. Guardá event.id para deduplicar; puede repetirse y los eventos pueden llegar fuera de orden. Consultá el recurso por ID para obtener su estado actual.

Respondé 2xx después de guardar el evento. Las entregas tienen hasta 7 intentos, con esperas de 1 minuto, 5 minutos, 15 minutos, 1 hora, 6 horas y 24 horas. Un destino inválido o permisos revocados detienen la entrega. Consultá ?action=entregas&id=WEBHOOK_ID y reenviá una entrega mediante {"action":"reenviar","delivery_id":"123"}.

Eventos: contactos.created, contactos.updated, productos.created, productos.updated, stock.created, stock.updated, presupuestos.created, presupuestos.updated, pedidos.created, pedidos.updated, ventas.created, ventas.updated, cobros.created, cobros.updated, comprobantes.created, comprobantes.updated, devoluciones.created, devoluciones.updated, leads.created, leads.updated. Los cambios de interfaz y procesos internos también se registran mediante eventos transaccionales.

Errores y recuperación

HTTPQué revisar
400Objeto JSON inválido.
401Token ausente, inválido o revocado.
403Permisos del token, usuario operativo, módulo o rango.
404ID inexistente, de otra empresa o fuera de tu visibilidad.
409Identidad duplicada, versión antigua, stock insuficiente o transición no disponible.
413Cuerpo de más de 2 MiB; dividilo en lotes.
415Falta Content-Type: application/json.
422Campos obligatorios, tipos, moneda, importes o referencias inválidos.
429Esperá el tiempo de Retry-After y conservá la clave de operación.
500Consultá el resultado y reintentá con la misma clave.
503La migración v2 todavía no está instalada.

Cortes durante facturación

pending espera al worker; processing está en curso; done tiene comprobante autorizado; rejected indica rechazo fiscal y necesita datos corregidos; failed falló antes de confirmar una emisión; uncertain exige conciliar la numeración reservada. El reintento de un resultado incierto consulta ARCA antes de emitir. Si no puede confirmarse, permanece pendiente de conciliación: no se genera otra factura a ciegas.

La caída de ARCA no revierte ni duplica la venta o sus cobros. La activación fiscal usa los certificados y el ambiente configurados para la empresa; las pruebas se hacen en homologación.

Compatibilidad y límites de esta entrega

La API v1 conserva su URL, sus tokens y su respuesta. La v2 usa otro contrato. No incluye pasarelas bancarias, múltiples monedas de escritura, financiación nueva ni comprobantes con varias alícuotas en una misma solicitud. Las devoluciones automáticas requieren el detalle trazable v2; los históricos permanecen consultables.

Cambios

2.0.0: API comercial, permisos por recurso, idempotencia, control de versiones, lotes, webhooks y facturación asíncrona. Requiere instalación y habilitación administrativa.

Compatibilidad: API de ingreso de leads v1

Endpoint y autenticacion

Metodo

POST

URL

https://www.plusdiario.com.ar/api/v1/leads/ingest.php
Header obligatorio: Authorization: Bearer TU_TOKEN_API

El token API se genera desde CRM en Control de Empresa - API de Ingesta de Leads Externos.

Campos recomendados

Campo Tipo Obligatorio Descripcion
sourcestringrecomendadoOrigen del lead (ej: web_form, landing, ecommerce). Si se omite, se usa externo.
nombrestringsiNombre del prospecto.
telefonostringsi*Telefono del prospecto. *obligatorio si no viene email.
emailstringsi*Email del prospecto. *obligatorio si no viene telefono.
mensajestringsiConsulta o texto enviado por el lead.
source_detailstringnoDetalle del origen (ej: landing-opticas-abril).
external_idstringnoID externo para dedupe estricto.
ad_id / campaign_idstringnoDatos de atribucion publicitaria.
metadataobjectnoUTMs u otros datos auxiliares.

Ejemplos

JSON

{
  "source": "web_form",
  "source_detail": "landing-opticas",
  "external_id": "lead-123",
  "nombre": "Juan Perez",
  "telefono": "3585180557",
  "email": "juan@email.com",
  "mensaje": "Quiero mas informacion",
  "ad_id": "120241033668400097",
  "campaign_id": "120241033668380097",
  "metadata": {
    "utm_source": "google",
    "utm_campaign": "abril"
  }
}

cURL

curl -X POST "https://www.plusdiario.com.ar/api/v1/leads/ingest.php" \
  -H "Authorization: Bearer TU_TOKEN_API" \
  -H "Content-Type: application/json" \
  -d '{
    "source":"web_form",
    "nombre":"Juan Perez",
    "telefono":"3585180557",
    "mensaje":"Quiero mas informacion"
  }'
Respuesta esperada: {"status":"ok","lead_id":1234,"deduped":false}