{
	"asyncapi": "3.0.0",
	"info": {
		"title": "FacturaDirecta Webhooks",
		"version": "2.0.0",
		"description": "API de webhooks de FacturaDirecta. Permite recibir notificaciones en tiempo real cuando ocurren eventos en tu empresa.\n\n## Verificación de la firma\n\nCada petición incluye la cabecera `Webhook-Signature` con el formato `t=<timestamp>,v1=<firma>`:\n\n- **t**: Unix timestamp (segundos) del momento del envío\n- **v1**: HMAC-SHA256 del string `<timestamp>.<payload_json>` firmado con tu signing secret\n\n## Seguridad\n\n- Siempre verifica la firma antes de procesar el evento\n- Rechaza eventos con `t` más antiguo de 5 minutos para evitar replay attacks\n- Solo se aceptan endpoints HTTPS\n",
		"contact": {
			"name": "Soporte API FacturaDirecta",
			"email": "info@facturadirecta.com",
			"url": "https://www.facturadirecta.com/ayuda/"
		},
		"license": {
			"name": "Propietario"
		}
	},
	"servers": {
		"production": {
			"host": "app.facturadirecta.com",
			"protocol": "https",
			"description": "Servidor de producción. Los eventos tienen `livemode: true`.",
			"security": [
				{
					"$ref": "#/components/securitySchemes/webhookSignature"
				}
			]
		},
		"sandbox": {
			"host": "app.facturadirecta.com",
			"protocol": "https",
			"description": "Servidor sandbox. Usar empresas con ID `com_sandbox_*`. Los eventos tienen `livemode: false`.",
			"security": [
				{
					"$ref": "#/components/securitySchemes/webhookSignature"
				}
			]
		}
	},
	"channels": {
		"invoice.created": {
			"address": "invoice.created",
			"description": "Se dispara cuando se crea una nueva factura",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_created": {
					"$ref": "#/components/messages/invoice_created"
				}
			}
		},
		"invoice.updated": {
			"address": "invoice.updated",
			"description": "Se dispara cuando se actualiza una factura",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_updated": {
					"$ref": "#/components/messages/invoice_updated"
				}
			}
		},
		"invoice.archived": {
			"address": "invoice.archived",
			"description": "Se dispara cuando se archiva una factura",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_archived": {
					"$ref": "#/components/messages/invoice_archived"
				}
			}
		},
		"invoice.unarchived": {
			"address": "invoice.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) una factura",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_unarchived": {
					"$ref": "#/components/messages/invoice_unarchived"
				}
			}
		},
		"invoice.sent": {
			"address": "invoice.sent",
			"description": "Se dispara cuando se envía una factura por email",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_sent": {
					"$ref": "#/components/messages/invoice_sent"
				}
			}
		},
		"invoice.voided": {
			"address": "invoice.voided",
			"description": "Se dispara cuando se anula una factura",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_voided": {
					"$ref": "#/components/messages/invoice_voided"
				}
			}
		},
		"invoice.verifactu_sent": {
			"address": "invoice.verifactu_sent",
			"description": "Se dispara cuando AEAT procesa una factura VeriFactu. El payload contiene el snapshot del Invoice enriquecido con el campo `verifactu_result`.",
			"tags": [
				{
					"name": "Facturas"
				}
			],
			"messages": {
				"invoice_verifactu_sent": {
					"$ref": "#/components/messages/invoice_verifactu_sent"
				}
			}
		},
		"expense.created": {
			"address": "expense.created",
			"description": "Se dispara cuando se crea un nuevo gasto",
			"tags": [
				{
					"name": "Gastos"
				}
			],
			"messages": {
				"expense_created": {
					"$ref": "#/components/messages/expense_created"
				}
			}
		},
		"expense.updated": {
			"address": "expense.updated",
			"description": "Se dispara cuando se actualiza un gasto",
			"tags": [
				{
					"name": "Gastos"
				}
			],
			"messages": {
				"expense_updated": {
					"$ref": "#/components/messages/expense_updated"
				}
			}
		},
		"expense.archived": {
			"address": "expense.archived",
			"description": "Se dispara cuando se archiva un gasto",
			"tags": [
				{
					"name": "Gastos"
				}
			],
			"messages": {
				"expense_archived": {
					"$ref": "#/components/messages/expense_archived"
				}
			}
		},
		"expense.unarchived": {
			"address": "expense.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) un gasto",
			"tags": [
				{
					"name": "Gastos"
				}
			],
			"messages": {
				"expense_unarchived": {
					"$ref": "#/components/messages/expense_unarchived"
				}
			}
		},
		"contact.created": {
			"address": "contact.created",
			"description": "Se dispara cuando se crea un nuevo contacto",
			"tags": [
				{
					"name": "Contactos"
				}
			],
			"messages": {
				"contact_created": {
					"$ref": "#/components/messages/contact_created"
				}
			}
		},
		"contact.updated": {
			"address": "contact.updated",
			"description": "Se dispara cuando se actualiza un contacto",
			"tags": [
				{
					"name": "Contactos"
				}
			],
			"messages": {
				"contact_updated": {
					"$ref": "#/components/messages/contact_updated"
				}
			}
		},
		"contact.archived": {
			"address": "contact.archived",
			"description": "Se dispara cuando se archiva un contacto",
			"tags": [
				{
					"name": "Contactos"
				}
			],
			"messages": {
				"contact_archived": {
					"$ref": "#/components/messages/contact_archived"
				}
			}
		},
		"contact.unarchived": {
			"address": "contact.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) un contacto",
			"tags": [
				{
					"name": "Contactos"
				}
			],
			"messages": {
				"contact_unarchived": {
					"$ref": "#/components/messages/contact_unarchived"
				}
			}
		},
		"estimate.created": {
			"address": "estimate.created",
			"description": "Se dispara cuando se crea un nuevo presupuesto",
			"tags": [
				{
					"name": "Presupuestos"
				}
			],
			"messages": {
				"estimate_created": {
					"$ref": "#/components/messages/estimate_created"
				}
			}
		},
		"estimate.updated": {
			"address": "estimate.updated",
			"description": "Se dispara cuando se actualiza un presupuesto",
			"tags": [
				{
					"name": "Presupuestos"
				}
			],
			"messages": {
				"estimate_updated": {
					"$ref": "#/components/messages/estimate_updated"
				}
			}
		},
		"estimate.archived": {
			"address": "estimate.archived",
			"description": "Se dispara cuando se archiva un presupuesto",
			"tags": [
				{
					"name": "Presupuestos"
				}
			],
			"messages": {
				"estimate_archived": {
					"$ref": "#/components/messages/estimate_archived"
				}
			}
		},
		"estimate.unarchived": {
			"address": "estimate.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) un presupuesto",
			"tags": [
				{
					"name": "Presupuestos"
				}
			],
			"messages": {
				"estimate_unarchived": {
					"$ref": "#/components/messages/estimate_unarchived"
				}
			}
		},
		"delivery_note.created": {
			"address": "delivery_note.created",
			"description": "Se dispara cuando se crea un nuevo albarán",
			"tags": [
				{
					"name": "Albaranes"
				}
			],
			"messages": {
				"delivery_note_created": {
					"$ref": "#/components/messages/delivery_note_created"
				}
			}
		},
		"delivery_note.updated": {
			"address": "delivery_note.updated",
			"description": "Se dispara cuando se actualiza un albarán",
			"tags": [
				{
					"name": "Albaranes"
				}
			],
			"messages": {
				"delivery_note_updated": {
					"$ref": "#/components/messages/delivery_note_updated"
				}
			}
		},
		"delivery_note.archived": {
			"address": "delivery_note.archived",
			"description": "Se dispara cuando se archiva un albarán",
			"tags": [
				{
					"name": "Albaranes"
				}
			],
			"messages": {
				"delivery_note_archived": {
					"$ref": "#/components/messages/delivery_note_archived"
				}
			}
		},
		"delivery_note.unarchived": {
			"address": "delivery_note.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) un albarán",
			"tags": [
				{
					"name": "Albaranes"
				}
			],
			"messages": {
				"delivery_note_unarchived": {
					"$ref": "#/components/messages/delivery_note_unarchived"
				}
			}
		},
		"client_order.created": {
			"address": "client_order.created",
			"description": "Se dispara cuando se crea un nuevo pedido",
			"tags": [
				{
					"name": "Pedidos"
				}
			],
			"messages": {
				"client_order_created": {
					"$ref": "#/components/messages/client_order_created"
				}
			}
		},
		"client_order.updated": {
			"address": "client_order.updated",
			"description": "Se dispara cuando se actualiza un pedido",
			"tags": [
				{
					"name": "Pedidos"
				}
			],
			"messages": {
				"client_order_updated": {
					"$ref": "#/components/messages/client_order_updated"
				}
			}
		},
		"client_order.archived": {
			"address": "client_order.archived",
			"description": "Se dispara cuando se archiva un pedido",
			"tags": [
				{
					"name": "Pedidos"
				}
			],
			"messages": {
				"client_order_archived": {
					"$ref": "#/components/messages/client_order_archived"
				}
			}
		},
		"client_order.unarchived": {
			"address": "client_order.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) un pedido",
			"tags": [
				{
					"name": "Pedidos"
				}
			],
			"messages": {
				"client_order_unarchived": {
					"$ref": "#/components/messages/client_order_unarchived"
				}
			}
		},
		"purchase_order.created": {
			"address": "purchase_order.created",
			"description": "Se dispara cuando se crea una nueva orden de compra",
			"tags": [
				{
					"name": "Órdenes de compra"
				}
			],
			"messages": {
				"purchase_order_created": {
					"$ref": "#/components/messages/purchase_order_created"
				}
			}
		},
		"purchase_order.updated": {
			"address": "purchase_order.updated",
			"description": "Se dispara cuando se actualiza una orden de compra",
			"tags": [
				{
					"name": "Órdenes de compra"
				}
			],
			"messages": {
				"purchase_order_updated": {
					"$ref": "#/components/messages/purchase_order_updated"
				}
			}
		},
		"purchase_order.archived": {
			"address": "purchase_order.archived",
			"description": "Se dispara cuando se archiva una orden de compra",
			"tags": [
				{
					"name": "Órdenes de compra"
				}
			],
			"messages": {
				"purchase_order_archived": {
					"$ref": "#/components/messages/purchase_order_archived"
				}
			}
		},
		"purchase_order.unarchived": {
			"address": "purchase_order.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) una orden de compra",
			"tags": [
				{
					"name": "Órdenes de compra"
				}
			],
			"messages": {
				"purchase_order_unarchived": {
					"$ref": "#/components/messages/purchase_order_unarchived"
				}
			}
		},
		"transaction.created": {
			"address": "transaction.created",
			"description": "Se dispara cuando se crea una nueva transacción (apunte contable, pago bancario, apunte manual, etc.)",
			"tags": [
				{
					"name": "Transacciones"
				}
			],
			"messages": {
				"transaction_created": {
					"$ref": "#/components/messages/transaction_created"
				}
			}
		},
		"transaction.updated": {
			"address": "transaction.updated",
			"description": "Se dispara cuando se actualiza una transacción",
			"tags": [
				{
					"name": "Transacciones"
				}
			],
			"messages": {
				"transaction_updated": {
					"$ref": "#/components/messages/transaction_updated"
				}
			}
		},
		"transaction.archived": {
			"address": "transaction.archived",
			"description": "Se dispara cuando se archiva una transacción",
			"tags": [
				{
					"name": "Transacciones"
				}
			],
			"messages": {
				"transaction_archived": {
					"$ref": "#/components/messages/transaction_archived"
				}
			}
		},
		"transaction.unarchived": {
			"address": "transaction.unarchived",
			"description": "Se dispara cuando se recupera (desarchiva) una transacción",
			"tags": [
				{
					"name": "Transacciones"
				}
			],
			"messages": {
				"transaction_unarchived": {
					"$ref": "#/components/messages/transaction_unarchived"
				}
			}
		},
		"product.created": {
			"address": "product.created",
			"description": "Evento de tipo product.created",
			"tags": [
				{
					"name": "Productos"
				}
			],
			"messages": {
				"product_created": {
					"$ref": "#/components/messages/product_created"
				}
			}
		},
		"product.updated": {
			"address": "product.updated",
			"description": "Evento de tipo product.updated",
			"tags": [
				{
					"name": "Productos"
				}
			],
			"messages": {
				"product_updated": {
					"$ref": "#/components/messages/product_updated"
				}
			}
		},
		"product.archived": {
			"address": "product.archived",
			"description": "Evento de tipo product.archived",
			"tags": [
				{
					"name": "Productos"
				}
			],
			"messages": {
				"product_archived": {
					"$ref": "#/components/messages/product_archived"
				}
			}
		},
		"product.unarchived": {
			"address": "product.unarchived",
			"description": "Evento de tipo product.unarchived",
			"tags": [
				{
					"name": "Productos"
				}
			],
			"messages": {
				"product_unarchived": {
					"$ref": "#/components/messages/product_unarchived"
				}
			}
		},
		"verifactu_batch.sent": {
			"address": "verifactu_batch.sent",
			"description": "Se dispara cuando se envía un lote de facturas a AEAT (contiene el estado global del envío)",
			"tags": [
				{
					"name": "VeriFactu"
				}
			],
			"messages": {
				"verifactu_batch_sent": {
					"$ref": "#/components/messages/verifactu_batch_sent"
				}
			}
		},
		"inbox.scanned": {
			"address": "inbox.scanned",
			"description": "Se dispara cuando el escáner termina de procesar un item de la bandeja de entrada (cualquier origen: subido por API, recibido por email, sincronizado desde Google Drive o subido manualmente). El payload contiene el `InboxItem` completo con la extracción y el texto OCR — equivalente a `GET /inbox/{id}`. También se dispara si la extracción no produjo datos útiles (en ese caso `status` viene como `scan_failed` en el snapshot).",
			"tags": [
				{
					"name": "Bandeja de entrada"
				}
			],
			"messages": {
				"inbox_scanned": {
					"$ref": "#/components/messages/inbox_scanned"
				}
			}
		}
	},
	"operations": {
		"receive_invoice_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea una nueva factura",
			"channel": {
				"$ref": "#/channels/invoice.created"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.created/messages/invoice_created"
				}
			]
		},
		"receive_invoice_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza una factura",
			"channel": {
				"$ref": "#/channels/invoice.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.updated/messages/invoice_updated"
				}
			]
		},
		"receive_invoice_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva una factura",
			"channel": {
				"$ref": "#/channels/invoice.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.archived/messages/invoice_archived"
				}
			]
		},
		"receive_invoice_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) una factura",
			"channel": {
				"$ref": "#/channels/invoice.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.unarchived/messages/invoice_unarchived"
				}
			]
		},
		"receive_invoice_sent": {
			"action": "receive",
			"summary": "Se dispara cuando se envía una factura por email",
			"channel": {
				"$ref": "#/channels/invoice.sent"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.sent/messages/invoice_sent"
				}
			]
		},
		"receive_invoice_voided": {
			"action": "receive",
			"summary": "Se dispara cuando se anula una factura",
			"channel": {
				"$ref": "#/channels/invoice.voided"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.voided/messages/invoice_voided"
				}
			]
		},
		"receive_invoice_verifactu_sent": {
			"action": "receive",
			"summary": "Se dispara cuando AEAT procesa una factura VeriFactu. El payload contiene el snapshot del Invoice enriquecido con el campo `verifactu_result`.",
			"channel": {
				"$ref": "#/channels/invoice.verifactu_sent"
			},
			"messages": [
				{
					"$ref": "#/channels/invoice.verifactu_sent/messages/invoice_verifactu_sent"
				}
			]
		},
		"receive_expense_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea un nuevo gasto",
			"channel": {
				"$ref": "#/channels/expense.created"
			},
			"messages": [
				{
					"$ref": "#/channels/expense.created/messages/expense_created"
				}
			]
		},
		"receive_expense_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza un gasto",
			"channel": {
				"$ref": "#/channels/expense.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/expense.updated/messages/expense_updated"
				}
			]
		},
		"receive_expense_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva un gasto",
			"channel": {
				"$ref": "#/channels/expense.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/expense.archived/messages/expense_archived"
				}
			]
		},
		"receive_expense_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) un gasto",
			"channel": {
				"$ref": "#/channels/expense.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/expense.unarchived/messages/expense_unarchived"
				}
			]
		},
		"receive_contact_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea un nuevo contacto",
			"channel": {
				"$ref": "#/channels/contact.created"
			},
			"messages": [
				{
					"$ref": "#/channels/contact.created/messages/contact_created"
				}
			]
		},
		"receive_contact_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza un contacto",
			"channel": {
				"$ref": "#/channels/contact.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/contact.updated/messages/contact_updated"
				}
			]
		},
		"receive_contact_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva un contacto",
			"channel": {
				"$ref": "#/channels/contact.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/contact.archived/messages/contact_archived"
				}
			]
		},
		"receive_contact_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) un contacto",
			"channel": {
				"$ref": "#/channels/contact.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/contact.unarchived/messages/contact_unarchived"
				}
			]
		},
		"receive_estimate_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea un nuevo presupuesto",
			"channel": {
				"$ref": "#/channels/estimate.created"
			},
			"messages": [
				{
					"$ref": "#/channels/estimate.created/messages/estimate_created"
				}
			]
		},
		"receive_estimate_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza un presupuesto",
			"channel": {
				"$ref": "#/channels/estimate.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/estimate.updated/messages/estimate_updated"
				}
			]
		},
		"receive_estimate_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva un presupuesto",
			"channel": {
				"$ref": "#/channels/estimate.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/estimate.archived/messages/estimate_archived"
				}
			]
		},
		"receive_estimate_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) un presupuesto",
			"channel": {
				"$ref": "#/channels/estimate.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/estimate.unarchived/messages/estimate_unarchived"
				}
			]
		},
		"receive_delivery_note_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea un nuevo albarán",
			"channel": {
				"$ref": "#/channels/delivery_note.created"
			},
			"messages": [
				{
					"$ref": "#/channels/delivery_note.created/messages/delivery_note_created"
				}
			]
		},
		"receive_delivery_note_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza un albarán",
			"channel": {
				"$ref": "#/channels/delivery_note.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/delivery_note.updated/messages/delivery_note_updated"
				}
			]
		},
		"receive_delivery_note_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva un albarán",
			"channel": {
				"$ref": "#/channels/delivery_note.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/delivery_note.archived/messages/delivery_note_archived"
				}
			]
		},
		"receive_delivery_note_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) un albarán",
			"channel": {
				"$ref": "#/channels/delivery_note.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/delivery_note.unarchived/messages/delivery_note_unarchived"
				}
			]
		},
		"receive_client_order_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea un nuevo pedido",
			"channel": {
				"$ref": "#/channels/client_order.created"
			},
			"messages": [
				{
					"$ref": "#/channels/client_order.created/messages/client_order_created"
				}
			]
		},
		"receive_client_order_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza un pedido",
			"channel": {
				"$ref": "#/channels/client_order.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/client_order.updated/messages/client_order_updated"
				}
			]
		},
		"receive_client_order_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva un pedido",
			"channel": {
				"$ref": "#/channels/client_order.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/client_order.archived/messages/client_order_archived"
				}
			]
		},
		"receive_client_order_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) un pedido",
			"channel": {
				"$ref": "#/channels/client_order.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/client_order.unarchived/messages/client_order_unarchived"
				}
			]
		},
		"receive_purchase_order_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea una nueva orden de compra",
			"channel": {
				"$ref": "#/channels/purchase_order.created"
			},
			"messages": [
				{
					"$ref": "#/channels/purchase_order.created/messages/purchase_order_created"
				}
			]
		},
		"receive_purchase_order_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza una orden de compra",
			"channel": {
				"$ref": "#/channels/purchase_order.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/purchase_order.updated/messages/purchase_order_updated"
				}
			]
		},
		"receive_purchase_order_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva una orden de compra",
			"channel": {
				"$ref": "#/channels/purchase_order.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/purchase_order.archived/messages/purchase_order_archived"
				}
			]
		},
		"receive_purchase_order_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) una orden de compra",
			"channel": {
				"$ref": "#/channels/purchase_order.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/purchase_order.unarchived/messages/purchase_order_unarchived"
				}
			]
		},
		"receive_transaction_created": {
			"action": "receive",
			"summary": "Se dispara cuando se crea una nueva transacción (apunte contable, pago bancario, apunte manual, etc.)",
			"channel": {
				"$ref": "#/channels/transaction.created"
			},
			"messages": [
				{
					"$ref": "#/channels/transaction.created/messages/transaction_created"
				}
			]
		},
		"receive_transaction_updated": {
			"action": "receive",
			"summary": "Se dispara cuando se actualiza una transacción",
			"channel": {
				"$ref": "#/channels/transaction.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/transaction.updated/messages/transaction_updated"
				}
			]
		},
		"receive_transaction_archived": {
			"action": "receive",
			"summary": "Se dispara cuando se archiva una transacción",
			"channel": {
				"$ref": "#/channels/transaction.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/transaction.archived/messages/transaction_archived"
				}
			]
		},
		"receive_transaction_unarchived": {
			"action": "receive",
			"summary": "Se dispara cuando se recupera (desarchiva) una transacción",
			"channel": {
				"$ref": "#/channels/transaction.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/transaction.unarchived/messages/transaction_unarchived"
				}
			]
		},
		"receive_product_created": {
			"action": "receive",
			"summary": "Evento de tipo product.created",
			"channel": {
				"$ref": "#/channels/product.created"
			},
			"messages": [
				{
					"$ref": "#/channels/product.created/messages/product_created"
				}
			]
		},
		"receive_product_updated": {
			"action": "receive",
			"summary": "Evento de tipo product.updated",
			"channel": {
				"$ref": "#/channels/product.updated"
			},
			"messages": [
				{
					"$ref": "#/channels/product.updated/messages/product_updated"
				}
			]
		},
		"receive_product_archived": {
			"action": "receive",
			"summary": "Evento de tipo product.archived",
			"channel": {
				"$ref": "#/channels/product.archived"
			},
			"messages": [
				{
					"$ref": "#/channels/product.archived/messages/product_archived"
				}
			]
		},
		"receive_product_unarchived": {
			"action": "receive",
			"summary": "Evento de tipo product.unarchived",
			"channel": {
				"$ref": "#/channels/product.unarchived"
			},
			"messages": [
				{
					"$ref": "#/channels/product.unarchived/messages/product_unarchived"
				}
			]
		},
		"receive_verifactu_batch_sent": {
			"action": "receive",
			"summary": "Se dispara cuando se envía un lote de facturas a AEAT (contiene el estado global del envío)",
			"channel": {
				"$ref": "#/channels/verifactu_batch.sent"
			},
			"messages": [
				{
					"$ref": "#/channels/verifactu_batch.sent/messages/verifactu_batch_sent"
				}
			]
		},
		"receive_inbox_scanned": {
			"action": "receive",
			"summary": "Se dispara cuando el escáner termina de procesar un item de la bandeja de entrada (cualquier origen: subido por API, recibido por email, sincronizado desde Google Drive o subido manualmente). El payload contiene el `InboxItem` completo con la extracción y el texto OCR — equivalente a `GET /inbox/{id}`. También se dispara si la extracción no produjo datos útiles (en ese caso `status` viene como `scan_failed` en el snapshot).",
			"channel": {
				"$ref": "#/channels/inbox.scanned"
			},
			"messages": [
				{
					"$ref": "#/channels/inbox.scanned/messages/inbox_scanned"
				}
			]
		}
	},
	"components": {
		"messages": {
			"invoice_created": {
				"name": "invoice.created",
				"title": "invoice.created",
				"summary": "Se dispara cuando se crea una nueva factura",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_updated": {
				"name": "invoice.updated",
				"title": "invoice.updated",
				"summary": "Se dispara cuando se actualiza una factura",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_archived": {
				"name": "invoice.archived",
				"title": "invoice.archived",
				"summary": "Se dispara cuando se archiva una factura",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_unarchived": {
				"name": "invoice.unarchived",
				"title": "invoice.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) una factura",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_sent": {
				"name": "invoice.sent",
				"title": "invoice.sent",
				"summary": "Se dispara cuando se envía una factura por email",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_voided": {
				"name": "invoice.voided",
				"title": "invoice.voided",
				"summary": "Se dispara cuando se anula una factura",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"invoice_verifactu_sent": {
				"name": "invoice.verifactu_sent",
				"title": "invoice.verifactu_sent",
				"summary": "Se dispara cuando AEAT procesa una factura VeriFactu. El payload contiene el snapshot del Invoice enriquecido con el campo `verifactu_result`.",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_invoice"
				}
			},
			"expense_created": {
				"name": "expense.created",
				"title": "expense.created",
				"summary": "Se dispara cuando se crea un nuevo gasto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_bill"
				}
			},
			"expense_updated": {
				"name": "expense.updated",
				"title": "expense.updated",
				"summary": "Se dispara cuando se actualiza un gasto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_bill"
				}
			},
			"expense_archived": {
				"name": "expense.archived",
				"title": "expense.archived",
				"summary": "Se dispara cuando se archiva un gasto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_bill"
				}
			},
			"expense_unarchived": {
				"name": "expense.unarchived",
				"title": "expense.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) un gasto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_bill"
				}
			},
			"contact_created": {
				"name": "contact.created",
				"title": "contact.created",
				"summary": "Se dispara cuando se crea un nuevo contacto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_contact"
				}
			},
			"contact_updated": {
				"name": "contact.updated",
				"title": "contact.updated",
				"summary": "Se dispara cuando se actualiza un contacto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_contact"
				}
			},
			"contact_archived": {
				"name": "contact.archived",
				"title": "contact.archived",
				"summary": "Se dispara cuando se archiva un contacto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_contact"
				}
			},
			"contact_unarchived": {
				"name": "contact.unarchived",
				"title": "contact.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) un contacto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_contact"
				}
			},
			"estimate_created": {
				"name": "estimate.created",
				"title": "estimate.created",
				"summary": "Se dispara cuando se crea un nuevo presupuesto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_estimate"
				}
			},
			"estimate_updated": {
				"name": "estimate.updated",
				"title": "estimate.updated",
				"summary": "Se dispara cuando se actualiza un presupuesto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_estimate"
				}
			},
			"estimate_archived": {
				"name": "estimate.archived",
				"title": "estimate.archived",
				"summary": "Se dispara cuando se archiva un presupuesto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_estimate"
				}
			},
			"estimate_unarchived": {
				"name": "estimate.unarchived",
				"title": "estimate.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) un presupuesto",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_estimate"
				}
			},
			"delivery_note_created": {
				"name": "delivery_note.created",
				"title": "delivery_note.created",
				"summary": "Se dispara cuando se crea un nuevo albarán",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_deliveryNote"
				}
			},
			"delivery_note_updated": {
				"name": "delivery_note.updated",
				"title": "delivery_note.updated",
				"summary": "Se dispara cuando se actualiza un albarán",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_deliveryNote"
				}
			},
			"delivery_note_archived": {
				"name": "delivery_note.archived",
				"title": "delivery_note.archived",
				"summary": "Se dispara cuando se archiva un albarán",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_deliveryNote"
				}
			},
			"delivery_note_unarchived": {
				"name": "delivery_note.unarchived",
				"title": "delivery_note.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) un albarán",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_deliveryNote"
				}
			},
			"client_order_created": {
				"name": "client_order.created",
				"title": "client_order.created",
				"summary": "Se dispara cuando se crea un nuevo pedido",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_clientOrder"
				}
			},
			"client_order_updated": {
				"name": "client_order.updated",
				"title": "client_order.updated",
				"summary": "Se dispara cuando se actualiza un pedido",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_clientOrder"
				}
			},
			"client_order_archived": {
				"name": "client_order.archived",
				"title": "client_order.archived",
				"summary": "Se dispara cuando se archiva un pedido",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_clientOrder"
				}
			},
			"client_order_unarchived": {
				"name": "client_order.unarchived",
				"title": "client_order.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) un pedido",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_clientOrder"
				}
			},
			"purchase_order_created": {
				"name": "purchase_order.created",
				"title": "purchase_order.created",
				"summary": "Se dispara cuando se crea una nueva orden de compra",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_purchaseOrder"
				}
			},
			"purchase_order_updated": {
				"name": "purchase_order.updated",
				"title": "purchase_order.updated",
				"summary": "Se dispara cuando se actualiza una orden de compra",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_purchaseOrder"
				}
			},
			"purchase_order_archived": {
				"name": "purchase_order.archived",
				"title": "purchase_order.archived",
				"summary": "Se dispara cuando se archiva una orden de compra",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_purchaseOrder"
				}
			},
			"purchase_order_unarchived": {
				"name": "purchase_order.unarchived",
				"title": "purchase_order.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) una orden de compra",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_purchaseOrder"
				}
			},
			"transaction_created": {
				"name": "transaction.created",
				"title": "transaction.created",
				"summary": "Se dispara cuando se crea una nueva transacción (apunte contable, pago bancario, apunte manual, etc.)",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_transaction"
				}
			},
			"transaction_updated": {
				"name": "transaction.updated",
				"title": "transaction.updated",
				"summary": "Se dispara cuando se actualiza una transacción",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_transaction"
				}
			},
			"transaction_archived": {
				"name": "transaction.archived",
				"title": "transaction.archived",
				"summary": "Se dispara cuando se archiva una transacción",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_transaction"
				}
			},
			"transaction_unarchived": {
				"name": "transaction.unarchived",
				"title": "transaction.unarchived",
				"summary": "Se dispara cuando se recupera (desarchiva) una transacción",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_transaction"
				}
			},
			"product_created": {
				"name": "product.created",
				"title": "product.created",
				"summary": "Evento de tipo product.created",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_product"
				}
			},
			"product_updated": {
				"name": "product.updated",
				"title": "product.updated",
				"summary": "Evento de tipo product.updated",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_product"
				}
			},
			"product_archived": {
				"name": "product.archived",
				"title": "product.archived",
				"summary": "Evento de tipo product.archived",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_product"
				}
			},
			"product_unarchived": {
				"name": "product.unarchived",
				"title": "product.unarchived",
				"summary": "Evento de tipo product.unarchived",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_product"
				}
			},
			"verifactu_batch_sent": {
				"name": "verifactu_batch.sent",
				"title": "verifactu_batch.sent",
				"summary": "Se dispara cuando se envía un lote de facturas a AEAT (contiene el estado global del envío)",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_verifactu_batch"
				}
			},
			"inbox_scanned": {
				"name": "inbox.scanned",
				"title": "inbox.scanned",
				"summary": "Se dispara cuando el escáner termina de procesar un item de la bandeja de entrada (cualquier origen: subido por API, recibido por email, sincronizado desde Google Drive o subido manualmente). El payload contiene el `InboxItem` completo con la extracción y el texto OCR — equivalente a `GET /inbox/{id}`. También se dispara si la extracción no produjo datos útiles (en ese caso `status` viene como `scan_failed` en el snapshot).",
				"contentType": "application/json",
				"payload": {
					"$ref": "#/components/schemas/WebhookPayload_inbox_item"
				}
			}
		},
		"schemas": {
			"WebhookEventType": {
				"type": "string",
				"title": "WebhookEventType",
				"description": "Tipo de evento webhook",
				"enum": [
					"invoice.created",
					"invoice.updated",
					"invoice.archived",
					"invoice.unarchived",
					"invoice.sent",
					"invoice.voided",
					"invoice.verifactu_sent",
					"expense.created",
					"expense.updated",
					"expense.archived",
					"expense.unarchived",
					"contact.created",
					"contact.updated",
					"contact.archived",
					"contact.unarchived",
					"estimate.created",
					"estimate.updated",
					"estimate.archived",
					"estimate.unarchived",
					"delivery_note.created",
					"delivery_note.updated",
					"delivery_note.archived",
					"delivery_note.unarchived",
					"client_order.created",
					"client_order.updated",
					"client_order.archived",
					"client_order.unarchived",
					"purchase_order.created",
					"purchase_order.updated",
					"purchase_order.archived",
					"purchase_order.unarchived",
					"transaction.created",
					"transaction.updated",
					"transaction.archived",
					"transaction.unarchived",
					"product.created",
					"product.updated",
					"product.archived",
					"product.unarchived",
					"verifactu_batch.sent",
					"inbox.scanned"
				]
			},
			"WebhookBasePayload": {
				"type": "object",
				"title": "WebhookBasePayload",
				"description": "Estructura base de todos los eventos webhook de FacturaDirecta",
				"required": [
					"id",
					"type",
					"object_type",
					"created",
					"livemode",
					"company_id",
					"data"
				],
				"additionalProperties": false,
				"properties": {
					"id": {
						"type": "string",
						"pattern": "^whe_",
						"description": "ID único del evento. Formato: `whe_<uuid>`",
						"example": "whe_550e8400-e29b-41d4-a716-446655440000"
					},
					"type": {
						"$ref": "#/components/schemas/WebhookEventType"
					},
					"object_type": {
						"type": "string",
						"enum": [
							"invoice",
							"bill",
							"contact",
							"estimate",
							"deliveryNote",
							"clientOrder",
							"purchaseOrder",
							"transaction",
							"product",
							"verifactu_batch",
							"inbox_item"
						],
						"description": "Tipo del objeto que generó el evento"
					},
					"created": {
						"type": "integer",
						"description": "Unix timestamp (segundos) del momento en que se generó el evento",
						"example": 1706784000
					},
					"livemode": {
						"type": "boolean",
						"description": "`true` para eventos de producción, `false` para eventos de sandbox"
					},
					"company_id": {
						"type": "string",
						"description": "ID de la empresa en FacturaDirecta",
						"example": "com_550e8400-e29b-41d4-a716-446655440000"
					},
					"data": {
						"type": "object",
						"description": "Datos del evento",
						"required": [
							"object"
						],
						"properties": {
							"object": {
								"type": "object",
								"additionalProperties": true,
								"description": "Snapshot completo del documento en el momento del evento"
							},
							"previous_attributes": {
								"type": "object",
								"additionalProperties": true,
								"description": "Atributos previos (solo en eventos `.updated`). Solo incluye los campos que cambiaron."
							}
						}
					}
				}
			},
			"WebhookPayload_invoice": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "invoice",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Invoice"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_bill": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "bill",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Bill"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_contact": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "contact",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Contact"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_estimate": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "estimate",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Estimate"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_deliveryNote": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "deliveryNote",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/DeliveryNote"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_clientOrder": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "clientOrder",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/ClientOrder"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_purchaseOrder": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "purchaseOrder",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/PurchaseOrder"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_transaction": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "transaction",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Transaction"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_product": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "product",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/Product"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_verifactu_batch": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "verifactu_batch",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/VerifactuBatch"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"WebhookPayload_inbox_item": {
				"allOf": [
					{
						"$ref": "#/components/schemas/WebhookBasePayload"
					},
					{
						"type": "object",
						"properties": {
							"object_type": {
								"type": "string",
								"const": "inbox_item",
								"description": "Tipo del objeto afectado por el evento"
							},
							"data": {
								"type": "object",
								"properties": {
									"object": {
										"$ref": "#/components/schemas/InboxItem"
									},
									"previous_attributes": {
										"type": "object",
										"additionalProperties": true,
										"description": "Atributos previos del documento (solo en eventos .updated). Solo incluye los campos que cambiaron."
									}
								},
								"required": [
									"object"
								]
							}
						}
					}
				]
			},
			"Invoice": {
				"type": "object",
				"title": "Invoice",
				"description": "Factura de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único de la factura"
					},
					"type": {
						"type": "string",
						"const": "invoice"
					},
					"verifactu_result": {
						"type": "object",
						"description": "Presente solo en eventos invoice.verifactu_sent. Resultado del procesamiento por AEAT.",
						"properties": {
							"tipoOperation": {
								"type": "string",
								"enum": [
									"alta",
									"anulacion"
								]
							},
							"estadoRegistro": {
								"type": "string",
								"enum": [
									"Correcto",
									"AceptadoConErrores",
									"Incorrecto"
								],
								"description": "Estado del registro en AEAT (ausente si hubo error inesperado)"
							},
							"codigoErrorRegistro": {
								"type": "string",
								"description": "Código de error AEAT (si aplica)"
							},
							"descripcionErrorRegistro": {
								"type": "string",
								"description": "Descripción del error AEAT (si aplica)"
							},
							"unexpectedError": {
								"type": "string",
								"description": "Error inesperado antes de recibir respuesta (ausente en flow normal)"
							}
						}
					}
				}
			},
			"Bill": {
				"type": "object",
				"title": "Bill",
				"description": "Gasto de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del gasto"
					},
					"type": {
						"type": "string",
						"const": "bill"
					}
				}
			},
			"Contact": {
				"type": "object",
				"title": "Contact",
				"description": "Contacto de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del contacto"
					},
					"type": {
						"type": "string",
						"const": "contact"
					}
				}
			},
			"Estimate": {
				"type": "object",
				"title": "Estimate",
				"description": "Presupuesto de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del presupuesto"
					},
					"type": {
						"type": "string",
						"const": "estimate"
					}
				}
			},
			"DeliveryNote": {
				"type": "object",
				"title": "DeliveryNote",
				"description": "Albarán de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del albarán"
					},
					"type": {
						"type": "string",
						"const": "deliveryNote"
					}
				}
			},
			"ClientOrder": {
				"type": "object",
				"title": "ClientOrder",
				"description": "Pedido de cliente de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del pedido"
					},
					"type": {
						"type": "string",
						"const": "clientOrder"
					}
				}
			},
			"PurchaseOrder": {
				"type": "object",
				"title": "PurchaseOrder",
				"description": "Orden de compra de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único de la orden de compra"
					},
					"type": {
						"type": "string",
						"const": "purchaseOrder"
					}
				}
			},
			"Transaction": {
				"type": "object",
				"title": "Transaction",
				"description": "Movimiento bancario de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del movimiento bancario"
					},
					"type": {
						"type": "string",
						"const": "transaction"
					}
				}
			},
			"Product": {
				"type": "object",
				"title": "Product",
				"description": "Producto de FacturaDirecta. Ver documentación de la API REST para el schema completo.",
				"additionalProperties": true,
				"properties": {
					"uuid": {
						"type": "string",
						"description": "ID único del producto"
					},
					"type": {
						"type": "string",
						"const": "product"
					}
				}
			},
			"VerifactuBatch": {
				"type": "object",
				"title": "VerifactuBatch",
				"description": "Resultado de un envío de lote de facturas VeriFactu a AEAT.",
				"additionalProperties": true,
				"properties": {
					"type": {
						"type": "string",
						"const": "verifactu_batch"
					},
					"exchangeId": {
						"type": "string",
						"description": "ID único del intercambio con AEAT"
					},
					"invoiceIds": {
						"type": "array",
						"items": {
							"type": "string"
						},
						"description": "Referencias externas VeriFactu (RefExterna) de las facturas incluidas en el lote"
					},
					"estadoEnvio": {
						"type": "string",
						"enum": [
							"Correcto",
							"ParcialmenteCorrecto",
							"Incorrecto"
						],
						"description": "Estado global del envío (ausente si hubo error inesperado antes de recibir respuesta de AEAT)"
					},
					"error": {
						"type": "string",
						"description": "Mensaje de error en caso de fallo inesperado del envío (ausente en envíos completados)"
					}
				}
			},
			"InboxItem": {
				"type": "object",
				"title": "InboxItem",
				"description": "Item de la bandeja de entrada, mismo shape que devuelve `GET /inbox/{id}` en la API REST. Ver el OpenAPI de la API REST para el schema completo de los sub-objetos `scan` y `attachments`.",
				"additionalProperties": true,
				"properties": {
					"id": {
						"type": "string",
						"description": "ID del item (prefijo `tas_`)"
					},
					"status": {
						"type": "string",
						"enum": [
							"pending",
							"scanned",
							"scan_failed"
						],
						"description": "Estado del escaneo. En eventos `inbox.scanned` será `scanned` o `scan_failed`."
					},
					"source": {
						"type": "string",
						"enum": [
							"upload",
							"inbox",
							"googleDrive",
							"scanner"
						],
						"description": "Origen del item."
					},
					"title": {
						"type": "string"
					},
					"createdAt": {
						"type": "string",
						"format": "date-time"
					},
					"updatedAt": {
						"type": "string",
						"format": "date-time"
					},
					"archived": {
						"type": "boolean"
					},
					"attachments": {
						"type": "array",
						"items": {
							"type": "object",
							"additionalProperties": true
						}
					},
					"scan": {
						"type": "object",
						"additionalProperties": true,
						"description": "Resultado del escaneo (incluye OCR text y extracción estructurada)."
					}
				}
			}
		},
		"securitySchemes": {
			"webhookSignature": {
				"type": "httpApiKey",
				"name": "Webhook-Signature",
				"in": "header",
				"description": "Firma HMAC-SHA256 del payload. Formato: `t=<timestamp>,v1=<firma>`. Verifica esta firma para autenticar los eventos."
			}
		}
	}
}
