Fiscalapi response models
This page describes the Fiscalapi response models. The base models define the common structure that every object inherits, such as a CFDI product (CFDI: Mexico's electronic invoice), an invoice, or a person (any individual or legal entity registered in your tenant). The other models wrap successful responses and errors.
1. Base models
The base models form an inheritance chain that reuses the common properties. AuditableDto provides the creation and last-update dates. BaseDto inherits it, adds the unique identifier, and is the base of most API responses. CatalogDto inherits BaseDto and adds description to represent SAT catalogs (SAT: Mexico's tax authority, Servicio de Administración Tributaria).
1.1 AuditableDto
Audit fields that track when a record was created and when it was last updated.
Properties
- Name
createdAt- Type
- DateTime?
- Description
The date and time the record was created.
- Name
updatedAt- Type
- DateTime?
- Description
The date and time the record was last updated.
Example:
{
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
1.2 BaseDto
Inherits AuditableDto and adds the record's unique identifier. It's the base of most entities.
Properties
- Name
id- Type
- string?
- Description
The record's unique identifier.
- Name
Inherited- Type
- object?
Includes every property defined in
AuditableDto.
Example:
{
"id": "abc123xyz",
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
1.3 CatalogDto
Inherits BaseDto and adds the description. It represents a record from a SAT catalog, or a record with the same structure as one of those catalogs.
Properties
- Name
description- Type
- string?
- Description
The description of the catalog entry.
- Name
Inherited- Type
- object?
Includes every property defined in
BaseDto.
Example:
{
"id": "cat123",
"description": "Elemento de catálogo de ejemplo",
"createdAt": "2024-02-20T10:30:00",
"updatedAt": "2024-02-20T15:45:00"
}
2. Response models
These models define the structure Fiscalapi uses to report the result of each operation, for successful responses and for errors alike. The standard model is ApiResponse<T>. A 400 validation response carries a list of ValidationFailure in data, and a paginated query returns a PagedList<T>.
2.1 ApiResponse<T>
The standard response model in Fiscalapi. It contains the payload, the operation status, and additional metadata. The generic type T is the data type of the payload.
Properties
- Name
data- Type
- T??
- Description
The response payload: an object, a list, a primitive value, or null if there's no data. For example, when you retrieve an invoice, it contains the invoice; when you retrieve a list, it contains the list of invoices, or null if there are no records.
- Name
succeeded- Type
- bool?
- Description
Whether the request succeeded (
true) or failed (false).
- Name
message- Type
- string??
- Description
A context message you can show in your application or save in your logs. In a validation error (400), the failures arrive in
data(see ValidationFailure) and the value of this field is: Sorry, it's not me, it's you.
- Name
details- Type
- string??
- Description
Additional detail, usually the cause of an error or a failed validation. In a validation error (400), its value is: One or more validation failures have occurred.
- Name
httpStatusCode- Type
- HttpStatusCode?
- Description
The HTTP status code of the response.
- Name
traceIdentifier- Type
- string??
- Description
A unique identifier for the request, used for tracing and technical support. On a server error (5xx), include it when you contact support: it identifies the request in the Fiscalapi logs (see Server errors).
Example:
{
"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
Describes a validation failure detected before the request is processed. 400 (Bad Request) validation responses carry a list of these failures. Request parsing errors arrive in the same shape: a value of another type (for example, text in a number), malformed JSON, an empty body, a required field that is missing or null inside a complement (complemento, an XML extension the SAT defines for specific operations), or an invalid query parameter. In those failures, propertyName is the path of the value and errorMessage describes the cause.
In parsing errors, errorCode and formattedMessagePlaceholderValues are null, and a body that can't be read returns a single failure:
| Case | propertyName | errorMessage |
|---|---|---|
| A value of another type | Its path (for example, $.items[0].quantity) | The JSON parser's text, in English |
| Malformed JSON, or JSON with a different shape at the root (for example, a list instead of an object) | $ (the JSON root) | The JSON parser's text, in English |
An empty or null body | $ | El cuerpo de la petición es requerido y no debe estar vacío. (The request body is required and must not be empty.) |
A required field that is missing or null inside a complement | Its path (for example, Complement.CartaPorte.TranspInternacId) | 'transpInternacId' no debe estar vacío. ('transpInternacId' must not be empty.) |
| An invalid query parameter | The parameter (for example, PageNumber) | El valor 'abc' no es válido para PageNumber. (The value 'abc' isn't valid for PageNumber.) |
Queries to GET /api/v4/<resource>/load, such as the catalog query, check their six parameters before they run: sort, filter, group, select, totalSummary, and groupSummary. Each problem returns one failure, with propertyName set to the parameter that contains it (for example, sort), and all the failures arrive in the same response:
| Case | errorMessage |
|---|---|
| A field that doesn't exist in the resource (in any of the six parameters) | El campo '<campo>' no existe en este recurso. (The field '<field>' doesn't exist in this resource.) |
A field that is an object or a list in the resource, in any parameter except select, which accepts it. For example, country on people or packageIds on download requests. | 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. (The field '<field>' is an object or a list: it can't be used in sort, filter, group, or the summaries; use one of its simple fields.) |
A summaryType that doesn't exist, in totalSummary or groupSummary | El resumen '<tipo>' no existe: usa count, sum, avg, min o max. (The summary '<type>' doesn't exist: use count, sum, avg, min, or max.) |
sum or avg of a field that isn't numeric | El resumen '<tipo>' solo admite campos numéricos y '<campo>' no lo es. (The summary '<type>' only accepts numeric fields, and '<field>' isn't one.) |
A groupInterval that doesn't apply to the field, in group: a number that isn't greater than zero or that applies to a field that isn't numeric, a date unit (year, quarter, month, day, dayOfWeek, hour, minute, or second) on a field that isn't a date, or an interval that doesn't exist | 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. (The interval '<interval>' doesn't apply to the field '<field>': a number requires a numeric field, and year, quarter, month, day, dayOfWeek, hour, minute, or second require a date field.) |
| Malformed JSON in one of the six parameters | El parámetro '<parámetro>' no es un JSON válido. (The parameter '<parameter>' isn't valid JSON.) |
For an object, use one of its simple fields, for example country.id. Field names are case-insensitive.
Properties
- Name
propertyName- Type
- string?
- Description
The name of the property that failed.
- Name
errorMessage- Type
- string?
- Description
A technical message that describes the cause of the failure. Validation messages are in Spanish, for example 'tipoCambioUSD' debe ser mayor que '0'. ('tipoCambioUSD' must be greater than '0'.) In stamping (the certification by a SAT-authorized provider that makes a CFDI valid), the message names the field as the API does (see Stamping validation messages).
Some rules keep their own message in English, such as the password rule in the example below, and so do the JSON parser errors (malformed JSON or a value of another type). To identify the failure in your code, use
propertyName(anderrorCodewhen it's present), not the text.
- Name
attemptedValue- Type
- object?
- Description
The value that the request tried to set and that caused the failure. The value of a secret is never returned:
Case attemptedValueA secret "[masked: n]", where n is the length of the value receivedAn object or a list that contains a secret (for example, the whole taxCredentials)"[masked]"A secret that wasn't sent nullThe sign-in password rules ( PasswordorNewPassword), as in the examplenull: the failure doesn't include the valueA password that doesn't open the private key (.key). It applies to Issuer.TaxCredentials[<n>].Passwordwhen you stamp an invoice by value (you send every issuer, recipient, and item value in the request), and toPasswordwhen you upload tax files (the CSD and e.firma .cer and .key files you upload for a person) or sign the Carta Manifiesto (the letter in which a taxpayer authorizes its PAC to certify its CFDIs). See Certificates and private keys.nullThese values are secrets: the sign-in passwords (current and new), the CSD (Certificado de Sello Digital, the digital seal certificate used to sign CFDIs) password, which the person saves in their profile (
taxPassword), email confirmation codes, password reset codes, and the refresh token. The content and password of the CSD and e.firma (the SAT advanced electronic signature that identifies a taxpayer, formerly FIEL) certificates are secrets too (base64Fileandpasswordin each tax credential).
- Name
customState- Type
- object?
- Description
Additional state of the failure. It's always
null.
- Name
severity- Type
- Severity?
- Description
The severity of the failure, as a number. Fiscalapi uses
0(Error).
- Name
errorCode- Type
- string?
- Description
An internal code that identifies the cause of the failure.
- Name
formattedMessagePlaceholderValues- Type
- object?
- Description
The values used to build
errorMessage, by name. It'snullin failures that aren't built from values, such as the sign-in password rules.Name (examples) Value PropertyNameThe name of the property. PropertyPathThe path of the property. PropertyValueThe value received, with the same rule as attemptedValuefor secrets.MinLengthorTotalLengthDepends on the rule.
Example (creating a person with a 5-character password):
{
"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>
A paginated response: it contains the items on the current page and the pagination details.
Properties
- Name
items- Type
- T[]?
- Description
The items on the current page.
- Name
pageNumber- Type
- int?
- Description
The current page number.
- Name
totalPages- Type
- int?
- Description
The total number of pages.
- Name
totalCount- Type
- int?
- Description
The total number of items.
- Name
hasPreviousPage- Type
- bool?
- Description
Whether there's a previous page.
- Name
hasNextPage- Type
- bool?
- Description
Whether there's a next page.
Example:
{
"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"
}