Modelos de respuesta en Fiscalapi
Esta página describe los modelos de respuesta de FiscalAPI: los modelos base, que definen la estructura común que heredan todos los objetos (como producto, factura y persona), y los modelos que envuelven las respuestas exitosas y los errores.
1. Modelos base
Los modelos base forman una cadena de herencia que reutiliza las propiedades comunes. AuditableDto aporta las fechas de creación y de última actualización. BaseDto lo hereda, agrega el identificador único y es la base de la mayoría de las respuestas de la API. CatalogDto hereda BaseDto y agrega description para representar los catálogos del SAT.
1.1 AuditableDto
Campos de auditoría que registran cuándo se creó un registro y cuándo se actualizó por última vez.
Propiedades
- Name
createdAt- Type
- DateTime?
- Description
Fecha y hora en que se creó el registro.
- Name
updatedAt- Type
- DateTime?
- Description
Fecha y hora de la última actualización del registro.
Ejemplo:
{
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
1.2 BaseDto
Hereda AuditableDto y agrega el identificador único del registro. Es la base de la mayoría de las entidades.
Propiedades
- Name
id- Type
- string?
- Description
Identificador único del registro.
- Name
Heredados- Type
- object?
Incluye todas las propiedades definidas en
AuditableDto.
Ejemplo:
{
"id": "abc123xyz",
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
1.3 CatalogDto
Hereda BaseDto y agrega la descripción. Representa un registro de un catálogo del SAT o un registro con la misma estructura que uno de esos catálogos.
Propiedades
- Name
description- Type
- string?
- Description
Descripción del elemento del catálogo.
- Name
Heredados- Type
- object?
Incluye todas las propiedades definidas en
BaseDto.
Ejemplo:
{
"id": "cat123",
"description": "Elemento de catálogo de ejemplo",
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
2. Modelos de respuesta
Estos modelos definen la estructura con la que FiscalAPI comunica el resultado de cada operación, tanto en las respuestas exitosas como en los errores. El modelo estándar es ApiResponse<T>. Una respuesta 400 de validación trae en data una lista de ValidationFailure, y una consulta paginada trae un PagedList<T>.
2.1 ApiResponse<T>
Modelo estándar de respuesta en FiscalAPI. Contiene la carga útil, el estado de la operación y metadatos adicionales. El tipo genérico T es el tipo de datos de la carga útil.
Propiedades
- Name
data- Type
- T??
- Description
Carga útil de la respuesta: un objeto, una lista, un valor primitivo o null si no hay datos. Por ejemplo, al consultar una factura contiene la factura; al consultar un listado, contiene la lista de facturas o null si no existen registros.
- Name
succeeded- Type
- bool?
- Description
Indica si la solicitud fue exitosa (
true) o fallida (false).
- Name
message- Type
- string??
- Description
Mensaje de contexto que puedes mostrar en tu aplicación o guardar en tus registros. En un error de validación (400), las fallas llegan en
data(ver ValidationFailure) y el valor de este campo es: Sorry, it's not me, it's you.
- Name
details- Type
- string??
- Description
Detalle adicional, por lo general la causa de un error o de una validación fallida. En un error de validación (400), su valor es: One or more validation failures have occurred.
- Name
httpStatusCode- Type
- HttpStatusCode?
- Description
Código de estado HTTP de la respuesta.
- Name
traceIdentifier- Type
- string??
- Description
Identificador único de la solicitud, para rastrearla o para soporte técnico. En un error del servidor (5xx), inclúyelo al escribir a soporte: identifica la petición en los registros de Fiscalapi (ver Errores del servidor).
Ejemplo:
{
"data": {
"invoiceNumber": "FAP240304AU3-1",
"date": "2023-11-11T14:35:18",
"issuerTin": "FAP240304AU3",
"total": 197.80,
"currencyCode": "MXN",
"status": "Vigente",
"...": "..."
},
"succeeded": true,
"message": "Operación exitosa",
"details": "",
"httpStatusCode": 200,
"traceIdentifier": "ABC123XYZ"
}
2.2 ValidationFailure
Describe una falla de validación detectada antes de procesar la solicitud. Las respuestas 400 (Bad Request) de validación traen una lista de estas fallas. Los errores de lectura de la solicitud llegan con la misma forma: un valor de otro tipo (por ejemplo, texto en un número), un JSON mal formado, un cuerpo vacío, un campo obligatorio ausente o null dentro de un complemento, o un parámetro de consulta inválido. En esas fallas, propertyName es la ruta del valor y errorMessage describe la causa.
En los errores de lectura, errorCode y formattedMessagePlaceholderValues son null, y un cuerpo que no se puede leer responde una sola falla:
| Caso | propertyName | errorMessage |
|---|---|---|
| Un valor de otro tipo | Su ruta (por ejemplo, $.items[0].quantity) | El texto en inglés del lector de JSON |
| Un JSON mal formado o con otra forma en la raíz (por ejemplo, una lista en lugar de un objeto) | $ (la raíz del JSON) | El texto en inglés del lector de JSON |
Un cuerpo vacío o null | $ | El cuerpo de la petición es requerido y no debe estar vacío. |
Un campo obligatorio ausente o null dentro de un complemento | Su ruta (por ejemplo, Complement.CartaPorte.TranspInternacId) | 'transpInternacId' no debe estar vacío. |
| Un parámetro de consulta inválido | El parámetro (por ejemplo, PageNumber) | El valor 'abc' no es válido para PageNumber. |
Las consultas GET /api/v4/<recurso>/load, como la de los catálogos, revisan sus seis parámetros antes de consultar: sort, filter, group, select, totalSummary y groupSummary. Cada problema responde una falla, con propertyName igual al parámetro que lo trae (por ejemplo, sort), y todas llegan en la misma respuesta:
| Caso | errorMessage |
|---|---|
| Un campo que no existe en el recurso (en cualquiera de los seis parámetros) | El campo '<campo>' no existe en este recurso. |
Un campo que es un objeto o una lista del recurso, en cualquier parámetro salvo select, que sí lo admite. Por ejemplo, country en las personas o packageIds en las solicitudes de descarga. | El campo '<campo>' es un objeto o una lista: no se puede usar en sort, filter, group ni en los resúmenes; usa uno de sus campos simples. |
Un summaryType que no existe, en totalSummary o groupSummary | El resumen '<tipo>' no existe: usa count, sum, avg, min o max. |
sum o avg de un campo que no es numérico | El resumen '<tipo>' solo admite campos numéricos y '<campo>' no lo es. |
Un groupInterval que no aplica al campo, en group: un número que no es mayor que cero o que se aplica a un campo que no es numérico, una unidad de fecha (year, quarter, month, day, dayOfWeek, hour, minute o second) sobre un campo que no es fecha, o un intervalo que no existe | El intervalo '<intervalo>' no aplica al campo '<campo>': un número requiere un campo numérico y year, quarter, month, day, dayOfWeek, hour, minute o second un campo de fecha. |
| Un JSON mal formado en uno de los seis parámetros | El parámetro '<parámetro>' no es un JSON válido. |
De un objeto, usa uno de sus campos simples; por ejemplo, country.id. Los nombres de campo no distinguen mayúsculas y minúsculas.
Propiedades
- Name
propertyName- Type
- string?
- Description
Nombre de la propiedad que presentó la falla.
- Name
errorMessage- Type
- string?
- Description
Mensaje técnico que describe la causa de la falla. Los mensajes de validación están en español; por ejemplo: 'tipoCambioUSD' debe ser mayor que '0'. En el timbrado, el campo se nombra como en la API (ver Mensajes de validación del timbrado).
Algunas reglas conservan un mensaje propio en inglés, como la de la contraseña del ejemplo de abajo, igual que los errores del lector de JSON (JSON mal formado o un valor de otro tipo). Para identificar la falla en tu código, usa
propertyName(yerrorCodecuando lo trae), no el texto.
- Name
attemptedValue- Type
- object?
- Description
Valor que se intentó asignar y ocasionó la falla. El valor de un secreto nunca se devuelve:
Caso attemptedValueUn secreto "[masked: n]", donde n es la longitud del valor recibidoUn objeto o una lista que contiene un secreto (por ejemplo, taxCredentialscompleto)"[masked]"Un secreto que no se envió nullLas reglas de la contraseña de acceso ( PasswordoNewPassword), como en el ejemplonull: la falla no trae el valorUna contraseña que no abre la llave privada (.key), en Issuer.TaxCredentials[<n>].Passwordal timbrar por valores, o enPasswordal subir certificados y al firmar la Carta Manifiesto (ver Certificados y llaves privadas)nullSon secretos las contraseñas de acceso (actual y nueva), la contraseña del CSD que la persona guarda en su perfil (
taxPassword), los códigos de confirmación de correo y de restablecimiento de contraseña, el refresh token, y el contenido y la contraseña de los certificados CSD y FIEL (base64Fileypasswordde cada credencial).
- Name
customState- Type
- object?
- Description
Estado adicional de la falla. Siempre es
null.
- Name
severity- Type
- Severity?
- Description
Severidad de la falla, como número. Fiscalapi usa
0(Error).
- Name
errorCode- Type
- string?
- Description
Código interno que identifica la causa de la falla.
- Name
formattedMessagePlaceholderValues- Type
- object?
- Description
Valores con los que se armó
errorMessage, por nombre. Esnullen las fallas que no se arman con valores, como la de las reglas de la contraseña de acceso.Nombre (ejemplos) Valor PropertyNameNombre de la propiedad. PropertyPathRuta de la propiedad. PropertyValueValor recibido, con la misma regla que attemptedValuepara los secretos.MinLengthoTotalLengthSegún la regla.
Ejemplo (crear una persona con una contraseña de 5 caracteres):
{
"data": [
{
"propertyName": "Password",
"errorMessage": "Password must be at least 6 characters long and contain at least one uppercase letter (A-Z), one lowercase letter (a-z), one digit (0-9) and one character that is not a letter or a digit. Letters with accents and ñ are not uppercase or lowercase letters for this rule.",
"attemptedValue": null,
"customState": null,
"severity": 0,
"errorCode": "PasswordTooShort",
"formattedMessagePlaceholderValues": null
}
],
"succeeded": false,
"message": "Sorry, it's not me, it's you.",
"details": "One or more validation failures have occurred.",
"httpStatusCode": 400,
"traceIdentifier": "1071497CFECD493A975F14A639CF2B6B"
}
2.3 PagedList<T>
Respuesta paginada: contiene los elementos de la página actual y la información de paginación.
Propiedades
- Name
items- Type
- T[]?
- Description
Elementos de la página actual.
- Name
pageNumber- Type
- int?
- Description
Número de la página actual.
- Name
totalPages- Type
- int?
- Description
Número total de páginas.
- Name
totalCount- Type
- int?
- Description
Número total de elementos.
- Name
hasPreviousPage- Type
- bool?
- Description
Indica si hay una página anterior.
- Name
hasNextPage- Type
- bool?
- Description
Indica si hay una página siguiente.
Ejemplo:
{
"data": {
"items": [
{
"invoiceNumber": "INV001",
"date": "2023-05-01T10:00:00",
"issuerTin": "XAXX010101000",
"total": 120.50
},
{
"invoiceNumber": "INV002",
"date": "2023-05-02T09:30:00",
"issuerTin": "XEXX010101000",
"total": 95.00
}
],
"pageNumber": 1,
"totalPages": 3,
"totalCount": 5,
"hasPreviousPage": false,
"hasNextPage": true
},
"succeeded": true,
"message": "Se ha obtenido la lista de facturas",
"details": "",
"httpStatusCode": 200,
"traceIdentifier": "XYZ789ABC"
}