From 4042f03a916cf19337ee81f2614ef58337d3aa0f Mon Sep 17 00:00:00 2001 From: javorosas Date: Tue, 8 Sep 2026 21:07:56 +0200 Subject: [PATCH 1/8] docs: document localized API errors --- website/docs/getting-started/errors.mdx | 71 ++++++++++++++++++- website/docs/getting-started/install.mdx | 4 +- .../current/getting-started/errors.mdx | 71 ++++++++++++++++++- .../current/getting-started/install.mdx | 4 +- website/openapi_v2.en.yaml | 6 ++ website/openapi_v2.yaml | 6 ++ 6 files changed, 156 insertions(+), 6 deletions(-) diff --git a/website/docs/getting-started/errors.mdx b/website/docs/getting-started/errors.mdx index ba65e89cd..221d78844 100644 --- a/website/docs/getting-started/errors.mdx +++ b/website/docs/getting-started/errors.mdx @@ -2,11 +2,80 @@ sidebar_position: 7 --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Manejo de errores La API responde los errores en JSON y usa códigos de estado HTTP estándar. Para manejar errores de forma programática, usa `code`: es un string estable y predecible. -`message` está pensado para lectura humana. Hoy los mensajes de la API se devuelven en español. Pueden cambiar para mejorar claridad o soportar localización, así que no deberían usarse para branching de lógica. +`message` está pensado para lectura humana y puede devolverse en español o inglés. Puede cambiar para mejorar claridad, así que no debería usarse para branching de lógica. + +## Idioma de los mensajes + +En API V2, envía `Accept-Language: en` para recibir en inglés los mensajes de error definidos por Facturapi. Usa `es` para español. Se aceptan variantes regionales como `en-US` y `es-MX`, además de preferencias con prioridad como `es;q=0.5, en;q=0.9`. Sin el header o sin un idioma compatible, la API usa español. + +El idioma se decide en cada petición y no depende del idioma del usuario o de la organización. La localización cambia `message` y los mensajes catalogados de `errors[].message`; los códigos, paths, status HTTP y demás campos permanecen iguales. Los mensajes originales del SAT/PAC y los mensajes legacy no catalogados conservan su idioma original. + +Los SDKs ya permiten configurar headers para todas las peticiones de una instancia: + + + + +```javascript +const facturapi = new Facturapi('TU_API_KEY', { + headers: { 'Accept-Language': 'en' }, +}); +``` + + + + +```php +$facturapi = new Facturapi('TU_API_KEY', [ + 'httpClient' => new GuzzleHttp\Client([ + 'headers' => ['Accept-Language' => 'en'], + ]), +]); +``` + + + + +```java +OkHttpClient httpClient = new OkHttpClient.Builder() + .addInterceptor(chain -> chain.proceed(chain.request().newBuilder() + .header("Accept-Language", "en") + .build())) + .build(); + +Facturapi facturapi = new Facturapi( + FacturapiConfig.builder("TU_API_KEY") + .httpClient(httpClient) + .build()); +``` + + + + +```csharp +var httpClient = new HttpClient(); +httpClient.DefaultRequestHeaders.AcceptLanguage.ParseAdd("en"); +var facturapi = FacturapiClient.CreateWithCustomHttpClient( + "TU_API_KEY", httpClient); +``` + + + + +```bash +curl 'https://www.facturapi.io/v2/customers' \ + -H 'Authorization: Bearer TU_API_KEY' \ + -H 'Accept-Language: en' +``` + + + ## Objeto de error diff --git a/website/docs/getting-started/install.mdx b/website/docs/getting-started/install.mdx index 097a8da71..7ce484032 100644 --- a/website/docs/getting-started/install.mdx +++ b/website/docs/getting-started/install.mdx @@ -50,14 +50,14 @@ Usando Maven: io.facturapi facturapi-java - 1.0.0 + 2.1.0 ``` Usando Gradle: ```gradle -implementation("io.facturapi:facturapi-java:1.0.0") +implementation("io.facturapi:facturapi-java:2.1.0") ``` diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index d1fcb22d8..3827d7b8a 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -2,11 +2,80 @@ sidebar_position: 7 --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Error handling The API returns errors as JSON and uses standard HTTP status codes. For programmatic error handling, use `code`: it is a stable, predictable string. -`message` is meant for humans. Today, API messages are returned in Spanish. They may change to improve clarity or support localization, so avoid using them for branching logic. +`message` is meant for humans and can be returned in Spanish or English. It may change to improve clarity, so avoid using it for branching logic. + +## Message language + +In API V2, send `Accept-Language: en` to receive Facturapi-defined error messages in English. Use `es` for Spanish. Regional variants such as `en-US` and `es-MX` are supported, as are weighted preferences such as `es;q=0.5, en;q=0.9`. Missing or unsupported language preferences fall back to Spanish. + +The language is selected per request and does not depend on the user or organization language. Localization changes `message` and cataloged `errors[].message` values; codes, paths, HTTP status, and all other fields remain unchanged. Original SAT/PAC messages and uncataloged legacy messages retain their original language. + +The SDKs already support configuring headers for every request made by a client instance: + + + + +```javascript +const facturapi = new Facturapi('YOUR_API_KEY', { + headers: { 'Accept-Language': 'en' }, +}); +``` + + + + +```php +$facturapi = new Facturapi('YOUR_API_KEY', [ + 'httpClient' => new GuzzleHttp\Client([ + 'headers' => ['Accept-Language' => 'en'], + ]), +]); +``` + + + + +```java +OkHttpClient httpClient = new OkHttpClient.Builder() + .addInterceptor(chain -> chain.proceed(chain.request().newBuilder() + .header("Accept-Language", "en") + .build())) + .build(); + +Facturapi facturapi = new Facturapi( + FacturapiConfig.builder("YOUR_API_KEY") + .httpClient(httpClient) + .build()); +``` + + + + +```csharp +var httpClient = new HttpClient(); +httpClient.DefaultRequestHeaders.AcceptLanguage.ParseAdd("en"); +var facturapi = FacturapiClient.CreateWithCustomHttpClient( + "YOUR_API_KEY", httpClient); +``` + + + + +```bash +curl 'https://www.facturapi.io/v2/customers' \ + -H 'Authorization: Bearer YOUR_API_KEY' \ + -H 'Accept-Language: en' +``` + + + ## Error object diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx index 5fc130506..c558deafb 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx @@ -50,14 +50,14 @@ Using Maven: io.facturapi facturapi-java - 1.0.0 + 2.1.0 ``` Using Gradle: ```gradle -implementation("io.facturapi:facturapi-java:1.0.0") +implementation("io.facturapi:facturapi-java:2.1.0") ``` diff --git a/website/openapi_v2.en.yaml b/website/openapi_v2.en.yaml index 228ef47ae..3d902447f 100644 --- a/website/openapi_v2.en.yaml +++ b/website/openapi_v2.en.yaml @@ -31,6 +31,12 @@ info: The secret key you use to authenticate will determine both the environment in which the invoice will be created (Test or Live), as well as the organization to use as the issuer of your invoice or as the owner of the resource you request to create. + Send `Accept-Language: en` for English Facturapi error messages, or + `Accept-Language: es` for Spanish (the default). Regional variants and `q` + priorities are supported. External SAT/PAC messages retain their original language. + See [Error handling](https://docs.facturapi.io/en/docs/getting-started/errors) + for the full contract and examples for every SDK. + tags: - name: tools x-displayName: Tools diff --git a/website/openapi_v2.yaml b/website/openapi_v2.yaml index d20fba586..70c3ac04a 100644 --- a/website/openapi_v2.yaml +++ b/website/openapi_v2.yaml @@ -39,6 +39,12 @@ info: (Test o Live), así como la organización a utilizar como emisor de tu factura, o bien como dueña del recurso que solicites crear. + Envía `Accept-Language: en` para recibir mensajes de error de Facturapi en inglés, + o `Accept-Language: es` para español (predeterminado). Se admiten variantes regionales + y prioridades `q`. Los mensajes externos SAT/PAC conservan su idioma original. + Consulta [Manejo de errores](https://docs.facturapi.io/docs/getting-started/errors) + para el contrato completo y ejemplos con cada SDK. + tags: - name: tools x-displayName: Herramientas From cf4169d2ed8bef12724af641f71ba6bd4eddcb5f Mon Sep 17 00:00:00 2001 From: javorosas Date: Tue, 8 Sep 2026 22:31:18 +0200 Subject: [PATCH 2/8] docs(errors): sync payload size and billing period wording - payload_too_large may include the known limit in parentheses (100KB). - invalid_global_invoice_period uses stable, untranslated period values. --- website/docs/getting-started/errors.mdx | 4 ++++ .../current/getting-started/errors.mdx | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/website/docs/getting-started/errors.mdx b/website/docs/getting-started/errors.mdx index 221d78844..3791013fe 100644 --- a/website/docs/getting-started/errors.mdx +++ b/website/docs/getting-started/errors.mdx @@ -212,6 +212,8 @@ Esta lista es la referencia documentada de códigos raíz públicos de la API. P | `page_too_large` | La página solicitada excede el límite permitido. | | `payload_too_large` | El payload excede el tamaño máximo permitido. | +Cuando el servidor conoce el límite, `payload_too_large` lo incluye entre paréntesis, p. ej. `El payload excede el tamaño máximo permitido (100KB).` + ### TaxInfoValidationCode Estos códigos describen errores de información fiscal validados por Facturapi. Cuando la validación fiscal de un cliente u organización detecta un solo problema, aparece en `code`. Las validaciones de entrada y el endpoint de validación de información fiscal de un cliente los devuelven en `errors[].code`. @@ -335,6 +337,8 @@ Estos códigos describen errores de información fiscal validados por Facturapi. | `global_invoice_too_many_items` | El periodo contiene más de 5,000 recibos abiertos. Envía `limit_to_max_receipts` para facturar hasta 5,000 por llamada o usa rangos de fechas o subconjuntos de recibos. | | `invalid_global_invoice_period` | El rango de fechas debe estar dentro del mismo periodo de facturación: `{period}`. | +En `invalid_global_invoice_period`, `{period}` es un valor estable que no se traduce: `year`, `day`, `week`, `fortnight`, `month` o `two_months`. + ### RetentionErrorCode | Código | Descripción | diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index 3827d7b8a..f13a07964 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -210,7 +210,9 @@ This list is the documented reference for public root API codes. We may add new | `invalid_timezone` | The timezone is invalid. | | `multipart_limit_exceeded` | The multipart/form-data request exceeds the allowed limits. | | `page_too_large` | The requested page exceeds the allowed limit. | -| `payload_too_large` | The request payload exceeds the maximum allowed size. | +| `payload_too_large` | The payload exceeds the maximum allowed size. | + +When the server knows the limit, `payload_too_large` includes it in parentheses, e.g. `The payload exceeds the maximum allowed size (100KB).` ### TaxInfoValidationCode @@ -335,6 +337,8 @@ These codes describe tax-information errors validated by Facturapi. When a custo | `global_invoice_too_many_items` | The period contains more than 5,000 open receipts. Send `limit_to_max_receipts` to invoice up to 5,000 per request, or use smaller date ranges or receipt subsets. | | `invalid_global_invoice_period` | The date range must be within the same billing period: `{period}`. | +For `invalid_global_invoice_period`, `{period}` is a stable, untranslated value: `year`, `day`, `week`, `fortnight`, `month`, or `two_months`. + ### RetentionErrorCode | Code | Description | From 5d68a7a0ec12c66a4e6f27eb1d19334181ce0421 Mon Sep 17 00:00:00 2001 From: javorosas Date: Tue, 8 Sep 2026 22:34:45 +0200 Subject: [PATCH 3/8] docs(errors): billing period is rendered in the response language MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit {period} keeps a stable canonical value and is localized at render time (e.g. año/year, bimestre/two-month period). --- website/docs/getting-started/errors.mdx | 2 +- .../current/getting-started/errors.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/getting-started/errors.mdx b/website/docs/getting-started/errors.mdx index 3791013fe..7e85b3e58 100644 --- a/website/docs/getting-started/errors.mdx +++ b/website/docs/getting-started/errors.mdx @@ -337,7 +337,7 @@ Estos códigos describen errores de información fiscal validados por Facturapi. | `global_invoice_too_many_items` | El periodo contiene más de 5,000 recibos abiertos. Envía `limit_to_max_receipts` para facturar hasta 5,000 por llamada o usa rangos de fechas o subconjuntos de recibos. | | `invalid_global_invoice_period` | El rango de fechas debe estar dentro del mismo periodo de facturación: `{period}`. | -En `invalid_global_invoice_period`, `{period}` es un valor estable que no se traduce: `year`, `day`, `week`, `fortnight`, `month` o `two_months`. +En `invalid_global_invoice_period`, `{period}` identifica el periodo con un valor estable (`year`, `day`, `week`, `fortnight`, `month` o `two_months`) y se muestra en el idioma de la respuesta, p. ej. `año` o `year`, `bimestre` o `two-month period`. ### RetentionErrorCode diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index f13a07964..8fc59f828 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -337,7 +337,7 @@ These codes describe tax-information errors validated by Facturapi. When a custo | `global_invoice_too_many_items` | The period contains more than 5,000 open receipts. Send `limit_to_max_receipts` to invoice up to 5,000 per request, or use smaller date ranges or receipt subsets. | | `invalid_global_invoice_period` | The date range must be within the same billing period: `{period}`. | -For `invalid_global_invoice_period`, `{period}` is a stable, untranslated value: `year`, `day`, `week`, `fortnight`, `month`, or `two_months`. +For `invalid_global_invoice_period`, `{period}` identifies the period with a stable value (`year`, `day`, `week`, `fortnight`, `month`, or `two_months`) and is rendered in the response language, e.g. `año`/`year` or `bimestre`/`two-month period`. ### RetentionErrorCode From a5432b0847cea2320e04817712fe3bb7937ff3e6 Mon Sep 17 00:00:00 2001 From: javorosas Date: Thu, 10 Sep 2026 13:35:36 +0200 Subject: [PATCH 4/8] docs(errors): use Basic auth in curl examples Facturapi authenticates with HTTP Basic, so the cURL example now passes the API key with -u instead of an Authorization: Bearer header. --- website/docs/getting-started/errors.mdx | 2 +- .../current/getting-started/errors.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/getting-started/errors.mdx b/website/docs/getting-started/errors.mdx index 7e85b3e58..0ec70b824 100644 --- a/website/docs/getting-started/errors.mdx +++ b/website/docs/getting-started/errors.mdx @@ -70,7 +70,7 @@ var facturapi = FacturapiClient.CreateWithCustomHttpClient( ```bash curl 'https://www.facturapi.io/v2/customers' \ - -H 'Authorization: Bearer TU_API_KEY' \ + -u 'TU_API_KEY:' \ -H 'Accept-Language: en' ``` diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index 8fc59f828..5269bd56a 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -70,7 +70,7 @@ var facturapi = FacturapiClient.CreateWithCustomHttpClient( ```bash curl 'https://www.facturapi.io/v2/customers' \ - -H 'Authorization: Bearer YOUR_API_KEY' \ + -u 'YOUR_API_KEY:' \ -H 'Accept-Language: en' ``` From 0a6e7a626e5f9e1e5a905bf5c4a880a035224094 Mon Sep 17 00:00:00 2001 From: javorosas Date: Thu, 10 Sep 2026 13:35:39 +0200 Subject: [PATCH 5/8] docs(install): update the Java SDK version in the install examples Point the Maven and Gradle snippets to 2.2.0, the latest published version, in both languages. --- website/docs/getting-started/install.mdx | 4 ++-- .../current/getting-started/install.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/getting-started/install.mdx b/website/docs/getting-started/install.mdx index 7ce484032..32b787601 100644 --- a/website/docs/getting-started/install.mdx +++ b/website/docs/getting-started/install.mdx @@ -50,14 +50,14 @@ Usando Maven: io.facturapi facturapi-java - 2.1.0 + 2.2.0 ``` Usando Gradle: ```gradle -implementation("io.facturapi:facturapi-java:2.1.0") +implementation("io.facturapi:facturapi-java:2.2.0") ``` diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx index c558deafb..148fddad0 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/install.mdx @@ -50,14 +50,14 @@ Using Maven: io.facturapi facturapi-java - 2.1.0 + 2.2.0 ``` Using Gradle: ```gradle -implementation("io.facturapi:facturapi-java:2.1.0") +implementation("io.facturapi:facturapi-java:2.2.0") ``` From e3e7d5f2b9ec661ec15787bc3f28bc39a2badf0f Mon Sep 17 00:00:00 2001 From: javorosas Date: Thu, 10 Sep 2026 13:35:39 +0200 Subject: [PATCH 6/8] docs(errors): restore the published payload_too_large description Leave the documented description of payload_too_large as published so this update only adds the localization content. --- .../current/getting-started/errors.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index 5269bd56a..cfcb95bab 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -210,7 +210,7 @@ This list is the documented reference for public root API codes. We may add new | `invalid_timezone` | The timezone is invalid. | | `multipart_limit_exceeded` | The multipart/form-data request exceeds the allowed limits. | | `page_too_large` | The requested page exceeds the allowed limit. | -| `payload_too_large` | The payload exceeds the maximum allowed size. | +| `payload_too_large` | The request payload exceeds the maximum allowed size. | When the server knows the limit, `payload_too_large` includes it in parentheses, e.g. `The payload exceeds the maximum allowed size (100KB).` From c305d431283d5cbd24fa59339f8c65f8c0d6896b Mon Sep 17 00:00:00 2001 From: javorosas Date: Thu, 10 Sep 2026 13:47:34 +0200 Subject: [PATCH 7/8] docs(errors): use Bearer auth in the curl examples --- website/docs/getting-started/errors.mdx | 2 +- .../current/getting-started/errors.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/getting-started/errors.mdx b/website/docs/getting-started/errors.mdx index 0ec70b824..7e85b3e58 100644 --- a/website/docs/getting-started/errors.mdx +++ b/website/docs/getting-started/errors.mdx @@ -70,7 +70,7 @@ var facturapi = FacturapiClient.CreateWithCustomHttpClient( ```bash curl 'https://www.facturapi.io/v2/customers' \ - -u 'TU_API_KEY:' \ + -H 'Authorization: Bearer TU_API_KEY' \ -H 'Accept-Language: en' ``` diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx index cfcb95bab..68324212f 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/getting-started/errors.mdx @@ -70,7 +70,7 @@ var facturapi = FacturapiClient.CreateWithCustomHttpClient( ```bash curl 'https://www.facturapi.io/v2/customers' \ - -u 'YOUR_API_KEY:' \ + -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Accept-Language: en' ``` From ba99328b26dcc70fe5d55d659a53b32aab73fa36 Mon Sep 17 00:00:00 2001 From: javorosas Date: Thu, 10 Sep 2026 17:52:10 +0200 Subject: [PATCH 8/8] docs(openapi): align invoice_types with the array form the API accepts --- website/openapi_v2.en.yaml | 2 -- website/openapi_v2.yaml | 2 -- 2 files changed, 4 deletions(-) diff --git a/website/openapi_v2.en.yaml b/website/openapi_v2.en.yaml index 3d902447f..0dfc443cd 100644 --- a/website/openapi_v2.en.yaml +++ b/website/openapi_v2.en.yaml @@ -3691,8 +3691,6 @@ paths: description: Filters issued or received invoices. - in: query name: invoice_types - style: form - explode: false schema: type: array uniqueItems: true diff --git a/website/openapi_v2.yaml b/website/openapi_v2.yaml index 70c3ac04a..b2638f2b0 100644 --- a/website/openapi_v2.yaml +++ b/website/openapi_v2.yaml @@ -3917,8 +3917,6 @@ paths: description: Filtra facturas emitidas o recibidas. - in: query name: invoice_types - style: form - explode: false schema: type: array uniqueItems: true