Fechas de la factura
El formato de fechaExpedicion y fechaOperacion, la regla de no-futuro, la zona horaria y qué espera cada administración.
Cada factura lleva hasta dos fechas, y las administraciones las tratan con reglas precisas. Esta página las reúne todas: el formato, la regla de no-futuro, la zona horaria en la que se evalúa «hoy» y el papel de la fecha en la identidad de la factura. Aplican igual a VeriFactu y a TicketBAI salvo donde se indica.
Los dos campos
| Campo | Qué significa | Obligatorio |
|---|---|---|
fechaExpedicion |
El día en que se emite la factura: la fecha que figura impresa en ella. | Sí |
fechaOperacion |
El día en que se realizó la operación: la entrega del bien o la prestación del servicio. | No |
Si no envías fechaOperacion, se entiende que coincide con fechaExpedicion.
Lo habitual es facturar durante o después de la operación: se entrega el día 1 y se factura el día 5, así que la fecha de operación es anterior o igual a la de expedición. La excepción son los anticipos (se factura hoy algo que se entregará más adelante), un caso legítimo que no todas las administraciones tratan igual: ver qué espera cada administración.
Formato
fechaExpedicion y fechaOperacion son cadenas JSON en formato dd-mm-aaaa, idéntico en las dos APIs:
| Regla | Válido | No válido |
|---|---|---|
| Dos dígitos en día y mes | "01-08-2026" |
"1-8-2026", "1-08-2026" |
| Cuatro dígitos en año | "01-08-2026" |
"01-08-26" |
| Separador guion, orden día-mes-año | "21-08-2026" |
"2026-08-21", "21/08/2026" |
| Fecha real del calendario | "29-02-2024" (bisiesto) |
"32-13-2026", "31-04-2026", "29-02-2026" |
| Cadena JSON | "01-08-2026" |
1082026, null, ["01-08-2026"] |
Los espacios al principio y al final se ignoran: " 01-08-2026 " se acepta.
Por qué se exigen los dos dígitos: el esquema oficial de TicketBAI define estas fechas con longitud exacta de 10 caracteres, y la fecha viaja tal cual al documento firmado. 1-8-2026 produciría un documento inválido. La API la rechaza en la entrada para que el error sea claro y no llegue nunca a la administración.
Años bisiestos: se validan de verdad, incluidas las reglas de siglo. 29-02-2024 se acepta; 29-02-2026, 29-02-1900 y 29-02-2100 se rechazan; 29-02-2000 se acepta.
La fecha de expedición no puede ser futura
Una factura no puede emitirse en el futuro. Si fechaExpedicion es posterior a hoy, la petición se rechaza con 400.
- El límite es inclusivo: la fecha de hoy es válida.
- «Hoy» se evalúa en hora peninsular española (
Europe/Madrid), no en UTC. Importa si tu sistema trabaja en otra zona horaria: entre las 00:00 y las 02:00 de la madrugada española, la fecha UTC todavía es la del día anterior, y un sistema en una zona por delante de la española puede llegar a calcular la fecha de «mañana» según Madrid. Calcula la fecha de expedición en hora peninsular. - Canarias va una hora por detrás de la Península, así que una fecha local canaria nunca queda por delante y no requiere ninguna consideración especial.
La AEAT y las tres haciendas forales aplican esta misma regla, de modo que la validación en la entrada no es una restricción de VeriBai: evita un rechazo posterior de la administración.
La regla se aplica también a las fechas que referencian otra factura. Esa factura ya existe, así que su fecha no puede estar en el futuro:
- la fecha de la factura que se rectifica (
rectificativa.facturasRectificadas[].fechaExpedicion), - la fecha de la factura que se anula (endpoints de anulación).
La fecha identifica la factura
fechaExpedicion no es un dato descriptivo: junto con serie y numero, identifica la factura. Tres consecuencias directas:
- La anulación localiza la factura por
serie+numero+fechaExpedicion. Si alguno de los tres no coincide exactamente con la factura original, la anulación no la encuentra. - La subsanación reenvía la misma factura corregida: conserva
serie,numeroyfechaExpedicion. No sirve para corregir la fecha de expedición: cambiarla equivale a declarar una factura distinta. - Si la fecha de expedición se envió mal y el registro ya se remitió, el camino correcto es anular la factura y emitir una nueva, no subsanar.
En TicketBAI, además, la fecha de expedición va incorporada al identificador TBAI (en formato ddmmaa) y, con él, al código QR de la factura.
La fecha de operación: qué espera cada administración
La API acepta una fechaOperacion futura, porque los anticipos son un caso real y la AEAT los contempla expresamente. Pero cada administración aplica su propio criterio:
| Administración | ¿fechaOperacion futura? |
Relación con fechaExpedicion |
|---|---|---|
| AEAT (VeriFactu) | Sí, únicamente con claveRegimen 14 o 15 (certificaciones de obra, anticipos), y como máximo hasta el año siguiente. |
Solo puede ser posterior a fechaExpedicion con claveRegimen 14 o 15. |
| Bizkaia (Batuz) | No: debe ser igual o anterior a hoy. | Debe ser igual o anterior a fechaExpedicion. |
| Araba | No publica una regla específica. | No publica una regla específica. |
| Gipuzkoa | No publica una regla específica. | No publica una regla específica. |
Si facturas un anticipo (una operación cuya fecha es posterior a la de expedición) y el emisor tributa en Bizkaia, ten en cuenta que la Hacienda Foral de Bizkaia no admite una fecha de operación posterior a la fecha de expedición ni posterior al día actual. En VeriFactu, informa
claveRegimen14o15cuando la fecha de operación sea posterior a la de expedición.
Dónde viaja cada campo
En VeriFactu las fechas de la factura van dentro de cabecera; en TicketBAI, en el nivel superior. El contrato completo está en las referencias de VeriFactu y TicketBAI.
VeriFactu
| Endpoint | Campo | Obligatorio |
|---|---|---|
POST /v1/verifactu/crear, PUT /v1/verifactu/subsanar |
cabecera.fechaExpedicion |
Sí |
POST /v1/verifactu/crear, PUT /v1/verifactu/subsanar |
cabecera.fechaOperacion |
No |
POST /v1/verifactu/crear (tipos R1–R5) |
rectificativa.facturasRectificadas[].fechaExpedicion |
Sí, dentro del bloque |
POST /v1/verifactu/crear (tipo F3) |
rectificativa.facturasSustituidas[].fechaExpedicion |
Sí, dentro del bloque |
POST /v1/verifactu/anular |
facturaAnulada.fechaExpedicion |
Sí |
TicketBAI
| Endpoint | Campo | Obligatorio |
|---|---|---|
POST /v1/ticketbai/crear, PUT /v1/ticketbai/subsanar |
fechaExpedicion |
Sí |
POST /v1/ticketbai/crear, PUT /v1/ticketbai/subsanar |
fechaOperacion |
No |
POST /v1/ticketbai/crear (tipos R1–R5) |
rectificativa.facturasRectificadas[].fechaExpedicion |
Sí, dentro del bloque |
POST /v1/ticketbai/anular |
fechaExpedicion (de la factura anulada) |
Sí |
En TicketBAI, el bloque rectificativa.facturasRectificadas cubre tanto las facturas rectificadas como las sustituidas: no existe un campo facturasSustituidas separado.
Las demás fechas de la petición
La regla de no-futuro no es exclusiva de fechaExpedicion. Otros tres campos la aplican, con la misma evaluación de «hoy» en hora peninsular:
| Campo | Dónde | Regla |
|---|---|---|
facturaAnulada.fechaExpedicion |
POST /v1/verifactu/anular |
dd-mm-aaaa real y no futura. Identifica una factura ya expedida, así que ninguna fecha futura puede corresponder a una: 400, con el código AEAT 1112 si es futura o 1105 si el formato es inválido o la fecha no existe en el calendario. |
rectificativa.facturasRectificadas[].fechaExpedicion y facturasSustituidas[] |
Alta de tipos R1–R5, en ambos sistemas |
dd-mm-aaaa real y no futura. El error nombra el elemento por su índice: rectificativa.facturasRectificadas[2].fechaExpedicion. |
horaExpedicion |
POST /v1/ticketbai/crear |
HH:MM:SS, 24 h, dos dígitos por componente. Opcional: si se omite, se usa la hora peninsular del momento. Se valida como hora real, no solo como formato: 24:00:00 se rechaza. |
Si omites horaExpedicion, la hora que queda en el documento firmado es la peninsular, la misma zona en la que se evalúa la fecha de al lado. Enviarla calculada en UTC es la forma habitual de que el documento lleve la fecha de hoy con la hora de ayer.
Errores
Todos los problemas de fecha se devuelven como 400 con el campo señalado por su nombre, nunca como un 5xx ni como un error genérico:
| API | Código | Cuándo |
|---|---|---|
| TicketBAI | VALIDATION_ERROR |
Formato incorrecto, fecha inexistente o fecha de expedición futura. |
| VeriFactu | VALIDATION_ERROR, con el código AEAT en el mensaje: 1105 (formato o fecha no válida) o 1112 (fecha de expedición posterior a hoy). |
Igual. |
Mensajes reales, como referencia:
fechaExpedicion debe estar en formato DD-MM-YYYY (recibido: 1-8-2026)
fechaExpedicion no es una fecha válida en formato DD-MM-YYYY (recibido: 32-13-2026)
fechaExpedicion no puede ser posterior a hoy (recibido: 01-01-2099; hoy: 22-08-2026, hora peninsular)
rectificativa.facturasRectificadas[0].fechaExpedicion no puede ser posterior a hoy: la factura que se rectifica ya fue emitida (recibido: 01-01-2099)
Una fecha mal formada produce un solo error: si el valor no es una fecha reconocible, se informa el problema de formato y no se añade además el de fecha futura.
Ejemplos
Suponiendo que hoy es 22-08-2026:
| Valor | Resultado |
|---|---|
"22-08-2026" |
✓ Hoy. El límite es inclusivo. |
"01-08-2026" |
✓ Pasado. |
"29-02-2024" |
✓ Año bisiesto real. |
" 01-08-2026 " |
✓ Los espacios se ignoran. |
fechaOperacion: "01-01-2027" |
✓ Anticipo. Revisa qué espera cada administración. |
"23-08-2026" |
✗ Fecha de expedición futura. |
"1-8-2026" |
✗ Día y mes deben llevar dos dígitos. |
"2026-08-22" |
✗ Orden ISO, no dd-mm-aaaa. |
"29-02-2026" |
✗ 2026 no es bisiesto. |
22082026 |
✗ Debe ser una cadena JSON. |