openapi: 3.0.3
servers:
  - url: https://api.verifacti.com/
info:
  title: Documentación de la API para gestionar NIFs
  contact:
    email: info@verifacti.com
    name: Contacto
    url: https://www.verifacti.com
  description: |

    # Funcionamiento básico

    Aquí encontrarás la documentación técnica de nuestra API para la gestión general de tus NIFs en nuestro sistema. En particular,
    se puede utilizar para dar de alta y de baja diferentes NIFs tanto en Verifactu como en TicketBai, el análogo a Verifactu en
    el País Vasco. Se pueden dar de alta NIFs en el entorno de test y de producción. Los NIFs de test envían facturas al entorno
    de test de la administración y no se contabilizan para la factura.

    &nbsp;

    Para un número pequeño de NIFs es posible crearlos, modificarlos y darlos de baja a mano usando nuestra plataforma.
    Sin embargo, para un gran volumen de NIFs esto se vuelve poco práctico, por lo que ponemos a vuestra disposición esta sencilla API
    para gestionarlos. Está incluida en el precio y se puede utilizar por cualquier usuario con una suscripción activa.

    &nbsp;

    La documentación de la API de Verifactu se encuentra en <a href="https://www.verifacti.com/docs">aquí</a>. Para TicketBai, disponemos
    de una API separada pero completamente análoga a la de Verifactu. Su documentación está <a href="https://www.verifacti.com/tb-docs">aquí</a>.

    &nbsp;

    En nuestra plataforma, encontrarás una API key para realizar todas tus llamadas a esta API, en https://app.verifacti.com/ajustes?tab=api-key. El endpoint más importante es el
    de crear un NIF, para lo cual hay que especificar los datos básicos así como la hacienda a la que se quiere vincular y el entorno.

    &nbsp;

    También se permite la creación de webhooks para recibir el resultado de la creación de registros de facturación.

    &nbsp;

    <a
      href="https://storage.googleapis.com/verifacti_non_sensitive/postman_nifs.json"
      download="nifs-docs.json"
      style="
        display: inline-block;
        padding: 6px 12px;
        background-color: #FF6C37;
        color: white;
        text-decoration: none;
        border-radius: 5px;
        font-weight: bold;
        font-family: Arial, sans-serif;
        box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    ">
      Colección de Postman
    </a>

    &nbsp;
tags:
  - name: NIFs
    description: |
      Se pueden crear NIFs en el entorno de test, que se comunican con el entorno de test de la administración. Estos están disponibles
      sin coste adicional y en ningún caso se contabilizan para la factura. También se pueden crear NIFs en el entorno de producción, que
      se comunican con el entorno de producción de la administración. Estos son los que se tienen en cuenta de cara a la facturación.

      &nbsp;

      Cuando se añade un NIF nuevo, éste se encuentra en estado "activo" y se puede empezar a usar para hacer llamadas a la administración.
      En cualquier momento, se puede activar o desactivar un NIF mediante el endpoint correspondiente. Los NIFs desactivados quedan
      guardados en nuestro sistema y no se seguirá cobrando por ellos. Se pueden activar en cualquier momento para continuar enviando facturas
      a la agencia tributaria en su nombre.
  - name: Validación
    description: |

      Existen muchas circunstancias en las que resulta útil validar que un NIF es correcto y está registrado en la administración, tanto para
      empresas (CIF) como ciudadanos nacionales (DNI) y residentes extranjeros (NIE). Para ello, disponemos de un endpoint específico que permite
      conocer el estado de un NIF en la administración.

      Además, proporcionamos un endpoint para comprobar la validez de IVAs intracomunitarios en el censo VIES.

      &nbsp;

      Estos endpoints de validación son los únicos que se pueden utilizar con una API de gestión de NIFs (vfn_...) o una de una empresa específica
      (vf_...).
  - name: Modelo de representación
    description: |
      Para generar y enviar facturas al entorno de producción de la AEAT usando la nuestra API, es necesario
      rellenar un modelo de otorgamiento de representación
      y <span style="font-weight: bold; text-decoration: underline">el NIF emisor de las facturas</span> debe firmalo digitalmente.
      Este documento se publicó en la resolución de 18 de diciembre
      de 2024 publicada en el BOE el 31 de diciembre de 2024, que se puede
      consultar <a target="_blank" href="https://www.boe.es/buscar/doc.php?id=BOE-A-2024-27600">aquí</a>.

      &nbsp;

      En esta sección explicamos qué pasos hay que seguir y cómo hacerlo a través de nuestra API.

      <div style="margin-top: 32px; margin-bottom: 6px; font-size: 16px; font-weight: bold;">
        1. Rellenar los datos del documento en PDF
      </div>

      <div style="margin-left: 18px;">
        El primer paso es descargarse el documento de otorgamiento de representación en PDF y rellenarlo. Para ello,
        disponemos del endpoint POST <code>/representacion/generar/:nif</code> al que se le pasan los datos relevantes y devuelve el PDF ya rellenado.
        Existe la posibilidad de generar el PDF para una persona física o una persona jurídica.
      </div>

      <div style="margin-top: 32px; margin-bottom: 6px; font-size: 16px; font-weight: bold;">
        2. Firmar el documento usando un certificado electrónico
      </div>

      <div style="margin-left: 18px;">
        Una vez obtenido el PDF con los datos rellenados, <span style="font-weight: bold; text-decoration: underline">el NIF emisor de las facturas</span> debe firmarlo usando un certificado electrónico. Para personas físicas,
        se utilizará un certificado de ciudadano y para personas jurídicas se utilizará un certificado de representante de entidad.
        Dichos certificados son archivos en formato .p12 o .pfx que, junto con una clave, permiten firmar electrónicamente documentos.
        En caso de no disponer de uno, se puede solicitar a varios organismos certificadores como, por ejemplo,
        la <a target="_blank" href="https://www.sede.fnmt.gob.es/">FNMT</a> o <a target="_blank" href="https://www.izenpe.eus/">Izenpe</a>.

        &nbsp;

        Para el proceso de firma del PDF con el certificado digital, existen numerosas opciones posibles. Desde Verifacti hemos optado
        por generar un simple programa que se puede descargar de manera gratuita y usarlo para firmar documentos en PDF electrónicamente.
        Se puede descargar como ejecutable de Windows o como script de Python.

        <div style="margin-top: 20px; margin-bottom: 6px; font-size: 14px; font-weight: bold;">
          a. Ejecutable de Windows para firmar
        </div>

        <div style="margin-left: 16px;">
          Descarga el ejecutable de Windows para firmar documentos en
          PDF <a href="https://storage.googleapis.com/verifacti_non_sensitive/ejecutable.zip" download="ejecutable.zip" >aquí</a>.
          Para usarlo, simplemente se tiene que indicar la ruta del PDF a firmar, la ruta del certificado y su contraseña.
          El resultado se guardará en la misma carpeta en la que está el PDF original con el sufijo "_firmado.pdf".
        </div>

        <pre style="
          display: flex;
          margin-left: 16px;
          margin-top: 20px;
          margin-bottom: 20px;
          background-color: #212d63;
          max-width: fit-content;
          color: #ffffff;
          padding: 14px;
          border-radius: 0.25rem;
          overflow-x: auto;
        ">
          <code style="
            font-family: monospace;
            font-size: 0.875rem;
          ">./firmador.exe /ruta/pdf.pdf /ruta/certificado.pfx "contraseña"</code>
        </pre>

        <div style="margin-top: 20px; margin-bottom: 6px; font-size: 14px; font-weight: bold;">
          b. Programa de Python para firmar
        </div>

        <div style="margin-left: 16px;">
          Puedes descargar el programa de Python para firmar documentos en
          PDF <a href="https://storage.googleapis.com/verifacti_non_sensitive/firmador.zip" download="firmador.zip" >aquí</a>.
          El modo de uso viene descrito en el fichero de ayuda. Simplemente hay que indicar la ruta del PDF a firmar, la ruta donde se encuentra
          el certificado y su contraseña. El resultado se guardará en la misma carpeta en la que está el PDF original con el sufijo "_firmado.pdf".
        </div>

        <pre style="
          display: flex;
          margin-left: 16px;
          margin-top: 20px;
          margin-bottom: 20px;
          background-color: #212d63;
          max-width: fit-content;
          color: #ffffff;
          padding: 14px;
          border-radius: 0.25rem;
          overflow-x: auto;
        ">
          <code style="
            font-family: monospace;
            font-size: 0.875rem;
          ">firmador.py /ruta/pdf.pdf /ruta/certificado.pfx 'contraseña'</code>
        </pre>

        <div style="margin-top: 20px; margin-bottom: 6px; font-size: 14px; font-weight: bold;">
          c. Aplicaciones de terceros
        </div>

        <div style="margin-left: 16px;">
          La aplicación más conocida para firmar documentos en PDF es <a href="https://get.adobe.com/es/reader/">Adobe Acrobat</a> que se puede
          descargar de manera gratuita y usarlo para firmar documentos en PDF electrónicamente. Este programa tiene una versión de
          pago pero es totalmente posible firmar documentos con la versión gratuita. En el menú de la izquierda se debe escoger la
          opción de <strong>Usar un certificado</strong>, como aparece en la <a className="link" target="_blank" href="https://app.verifacti.com/public/adobe.png">imagen</a>.
        </div>

        &nbsp;

        <div style="margin-left: 16px;">
          También se puede usar el programa <a href="https://firmaelectronica.gob.es/ciudadanos/descargas">AutoFirma</a>, creado por
          el Gobierno de España para facilitar la firma electrónica de documentos.
        </div>
      </div>

      <div style="margin-top: 32px; margin-bottom: 6px; font-size: 16px; font-weight: bold;">
        3. Subir el documento firmado a nuestra plataforma
      </div>

      <div style="margin-left: 16px;">
        Una vez obtenido el PDF firmado, se debe subir a nuestra plataforma. Para ello, disponemos del endpoint POST
        <code>/representacion/enviar/:nif</code> al que se le pasa el PDF firmado y devuelve el estado de la operación. La firma se valida
        de forma programática por nuestro lado y se comprueba que el NIF del documento coincida con el NIF del certificado. Para personas
        jurídicas se valida además el NIF del representante.
      </div>
  - name: Webhooks
    description: |
      Nuestra plataforma permite el uso de webhooks para recibir notificaciones automáticas cuando se genera un registro de facturación.
      Esta funcionalidad está diseñada para evitar consultas constantes a la API, permitiendo que tu sistema sea notificado de forma inmediata y
      eficiente cuando se dispone del resultado.

      &nbsp;

      Cada registro de facturación está vinculado a un NIF, y los webhooks pueden configurarse
      para escuchar eventos relacionados con uno o varios NIFs. Asimismo, un mismo NIF
      puede estar asociado a múltiples webhooks.

      &nbsp;

      La API proporciona endpoints para:
      <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
        <li>Crear nuevos webhooks</li>
        <li>Consultar webhooks existentes</li>
        <li>Modificar su configuración</li>
        <li>Eliminar webhooks</li>
        <li>Asociar y desasociar NIFs a webhooks</li>
      </ul>

      &nbsp;

      **Firma de notificaciones**

      Para mayor seguridad, es posible definir un valor `secret` al crear un webhook.
      Este secreto se utiliza para generar una firma digital (HMAC con el algoritmo SHA-256)
      que se incluye en cada notificación, dentro del header HTTP `X-Webhook-Signature`.

      &nbsp;

      Esta firma permite al receptor del webhook verificar que:
      <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
        <li>El mensaje fue enviado por nuestra API</li>
        <li>El contenido no fue modificado durante la transmisión</li>
      </ul>

      &nbsp;

      Para verificar la firma:
      <ol style="list-style: decimal; margin-top: 6px; margin-bottom: 0px;">
        <li>Debes obtener el cuerpo exacto del mensaje recibido (sin alterar).</li>
        <li>Usar el mismo secreto asociado al webhook para calcular una firma HMAC-SHA256 (en hexadecimal).</li>
        <li>Comparar la firma generada con la contenida en el header `X-Webhook-Signature`.</li>
      </ol>

      &nbsp;

      Si ambas firmas coinciden, puedes confiar en que el mensaje es auténtico.

      &nbsp;

      **Clave de idempotencia**

      Cada notificación incluye también el header `X-Webhook-Id`, cuyo valor es un identificador único (UUID v4) generado por nuestra API para esa notificación concreta. Este identificador es **estable a través de reintentos**: si una notificación es reintentada, todos los intentos llevan el mismo valor en `X-Webhook-Id`. Recomendamos utilizarlo como clave de idempotencia en tu sistema para evitar procesar dos veces la misma notificación.

      &nbsp;

      **Reintentos**

      Si tu endpoint responde con un código distinto de `2xx` (o no responde dentro del tiempo de espera), la notificación se reintentará automáticamente con _exponential backoff_. La política actual es:

      <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
        <li>Hasta <strong>5 intentos</strong> en total (1 envío inicial + 4 reintentos).</li>
        <li>Backoff exponencial entre <strong>30 segundos</strong> y <strong>1 hora</strong>.</li>
      </ul>

      &nbsp;

      Transcurridos los 5 intentos, el envío se descarta.

      &nbsp;

      **Estructura del payload**

      El cuerpo de la petición es un array JSON. Cada elemento corresponde con el resultado que devolvería el
      endpoint `Estado registro` de las APIs de Verifactu o TicketBai, según el tipo de NIF. Algunos campos solo
      están presentes para una de las dos APIs; el campo `estado` indica si los campos de error son aplicables.
      A la derecha se muestra un ejemplo de notificación con dos registros de facturación.

      <SchemaDefinition schemaRef="#/components/schemas/WebhookNotification" />
paths:
  /nifs:
    get:
      summary: Listar NIFs
      tags:
        - NIFs
      description: |
        Este endpoint devuelve una lista de todos los NIFs. Por defecto, devuelve tanto los activos como los inactivos en ambos entornos
        aunque permite filtrar solamente los activos o inactivos y el entorno.
      parameters:
        - in: query
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          description: Parámetro que permite filtrar los NIFs dependiendo del entorno. En caso de que no se incluya, se devolverán todos los NIFs.
          example: prod
        - in: query
          name: activos
          schema:
            type: boolean
          description: Parámetro que permite filtrar los NIFs activos o inactivos. En caso de que no se incluya, se devolverán todos los NIFs.
          example: true
        - in: query
          name: limite
          schema:
            type: integer
            maximum: 100
            minimum: 1
            default: 40
          description: Parámetro que permite limitar la cantidad de NIFs devueltos. El valor por defecto es 40 y el máximo es 100.
          example: 50
        - in: query
          name: pagina
          schema:
            type: integer
            default: 1
          description: Parámetro que permite paginar la lista de NIFs.
          example: 3
        - in: query
          name: label
          schema:
            type: string
          description: |
            Parámetro que permite filtrar los NIFs por etiqueta. Solo se devolverán los NIFs cuya etiqueta coincida exactamente.

            El valor debe enviarse codificado en URL (`encodeURIComponent` o equivalente), ya que las etiquetas pueden contener espacios o caracteres especiales (p. ej. `Cliente & Cía` → `Cliente%20%26%20C%C3%ADa`).
          example: Cliente A
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs?entorno=test&activos=true' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs?entorno=test&activos=true'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs?entorno=test&activos=true';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/nifs?entorno=test&activos=true", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs?entorno=test&activos=true";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/nifs?entorno=test&activos=true\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs?entorno=test&activos=true"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/nifs?entorno=test&activos=true");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs?entorno=test&activos=true"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: Lista de NIFs
          content:
            application/json:
              schema:
                type: array
                items:
                  properties:
                    nif:
                      description: NIF.
                      type: string
                    entorno:
                      description: Entorno del NIF. Puede ser "test" o "prod".
                      type: string
                    hacienda:
                      description: |
                        Hacienda a la que está vinculado el NIF. Los valores posibles son:
                        <ol style="list-style-type: disc">
                          <li>verifactu</li>
                          <li>alava</li>
                          <li>guipuzcoa</li>
                          <li>vizcaya</li>
                        </ol>
                      type: string
                    nombre:
                      description: Nombre y apellidos o razón social del NIF.
                      type: string
                    activo:
                      description: Indica si el NIF está activo o no.
                      type: boolean
                    representacion:
                      enum:
                        - Correcto
                        - Rechazado
                        - Inexistente
                      description: |
                        Indica el estado del modelo de representación del NIF. Los valores posibles son:
                        <ol style="list-style-type: disc">
                          <li>Correcto: El modelo de representación se ha recibido y se ha validado correctamente.</li>
                          <li>Rechazado: El modelo de representación ha sido recibido pero no se ha podido validar.</li>
                          <li>Inexistente: No se ha recibido el modelo de representación firmado.</li>
                        </ol>

                        Únicamente está presente este campo para los NIFs de Verifactu. Para NIFs de producción se requiere que el estado de la
                        representación sea "Correcto" para poder enviar facturas.
                      type: string
                    fecha_creacion:
                      description: Fecha de creación del NIF.
                      type: string
                    webhooks:
                      description: Lista de identificadores de los webhooks a los que esta asociado el NIF.
                      type: array
                      items:
                        type: string
                    label:
                      description: Etiqueta asociada al NIF. Puede ser `null` si no se ha asignado ninguna.
                      type: string
                    pagado_hasta:
                      type: string
                      description: |
                        Campo solo disponible para NIFs de producción, ya que son los únicos por los que hay que pagar.
                        Este campo indica la fecha hasta la que se ha pagado el NIF. En caso de que llegada esa fecha el NIF esté activo,
                        entonces se renovará automáticamente y dicha fecha se actualizará automáticamente.
                example:
                  - nif: B86561412
                    entorno: test
                    hacienda: verifactu
                    nombre: Mi empresa SL
                    activo: true
                    fecha_creacion: "2024-12-01T12:18:21.671Z"
                    representacion: Inexistente
                    webhooks:
                      - 17067405-8c32-4efe-a7cb-8fad93403997
                    label: Cliente A
                  - nif: C01345232
                    entorno: test
                    hacienda: alava
                    nombre: Mi empresa 2 SL
                    activo: true
                    fecha_creacion: "2025-01-01T09:08:41.645Z"
                    representacion: Correcto
                    webhooks: []
                    label: null
        "400":
          description: Parámetros de consulta inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    post:
      summary: Añadir NIFs
      tags:
        - NIFs
      description: |
        Mediante este endpoint se añaden nuevos NIFs.

        &nbsp;

        Si se quiere activar un NIF que ha sido previamente desactivado, se debe utilizar el endpoint correspondiente para
        ello y no crear uno nuevo. En caso de intentarlo, se devolverá un error 409.

        &nbsp;

        <span style="color: red">IMPORTANTE</span>: Para suscripciones anuales, al añadir nuevos NIFs en entorno de producción
        se abonará la cantidad correspondiente al momento y se generará una nueva factura que puede consultarse en nuestra plataforma,
        en la sección de facturación. Para evitar generar múltiples facturas, se pueden añadir varios NIFs a la vez y se abonarán todos juntos.
        Para suscripciones mensuales, se abonará la cantidad correspondiente a los nuevos NIFs en la siguiente factura mensual.

        &nbsp;

        Los NIFs de tipo `test` no se contabilizarán para la factura.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl --request POST 'https://api.verifacti.com/nifs' \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --header 'Content-Type: application/json' \
            --data-raw '[
              {
                "nif": "B86561412",
                "entorno": "test",
                "hacienda": "verifactu",
                "nombre": "Mi empresa SL",
                "direccion": "Calle Mayor 15",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              },
              {
                "nif": "B01345232",
                "entorno": "prod",
                "hacienda": "verifactu",
                "nombre": "Mi otra empresa SL",
                "direccion": "Gran Vía 22",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              }
            ]'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            }
            data = [
              {
                'nif': 'B86561412',
                'entorno': 'test',
                'hacienda': 'verifactu',
                'nombre': 'Mi empresa SL',
                'direccion': 'Calle Mayor 15',
                'cp': '28040',
                'poblacion': 'Madrid',
                'provincia': 'Madrid'
              },
              {
                'nif': 'B01345232',
                'entorno': 'prod',
                'hacienda': 'verifactu',
                'nombre': 'Mi otra empresa SL',
                'direccion': 'Gran Vía 22',
                'cp': '28040',
                'poblacion': 'Madrid',
                'provincia': 'Madrid'
              }
            ]
            response = requests.post(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            };
            const data = [
              {
                'nif': 'B86561412',
                'entorno': 'test',
                'hacienda': 'verifactu',
                'nombre': 'Mi empresa SL',
                'direccion': 'Calle Mayor 15',
                'cp': '28040',
                'poblacion': 'Madrid',
                'provincia': 'Madrid'
              },
              {
                'nif': 'B01345232',
                'entorno': 'prod',
                'hacienda': 'verifactu',
                'nombre': 'Mi otra empresa SL',
                'direccion': 'Gran Vía 22',
                'cp': '28040',
                'poblacion': 'Madrid',
                'provincia': 'Madrid'
              }
            ]
            fetch(url, { headers, method: 'POST', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = [
              {
                "nif": "B86561412",
                "entorno": "test",
                "hacienda": "verifactu",
                "nombre": "Mi empresa SL",
                "direccion": "Calle Mayor 15",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              },
              {
                "nif": "B01345232",
                "entorno": "prod",
                "hacienda": "verifactu",
                "nombre": "Mi otra empresa SL",
                "direccion": "Gran Vía 22",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              }
            ];

            const response = await axios.post("https://api.verifacti.com/nifs", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            [
              {
                "nif": "B86561412",
                "entorno": "test",
                "hacienda": "verifactu",
                "nombre": "Mi empresa SL",
                "direccion": "Calle Mayor 15",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              },
              {
                "nif": "B01345232",
                "entorno": "prod",
                "hacienda": "verifactu",
                "nombre": "Mi otra empresa SL",
                "direccion": "Gran Vía 22",
                "cp": "28040",
                "poblacion": "Madrid",
                "provincia": "Madrid"
              }
            ]
            JSON;

            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n[\n  {\n    \"nif\": \"B86561412\",\n    \"entorno\": \"test\",\n    \"hacienda\": \"verifactu\",\n    \"nombre\": \"Mi empresa SL\",\n    \"direccion\": \"Calle Mayor 15\",\n    \"cp\": \"28040\",\n    \"poblacion\": \"Madrid\",\n    \"provincia\": \"Madrid\"\n  },\n  {\n    \"nif\": \"B01345232\",\n    \"entorno\": \"prod\",\n    \"hacienda\": \"verifactu\",\n    \"nombre\": \"Mi otra empresa SL\",\n    \"direccion\": \"Gran Vía 22\",\n    \"cp\": \"28040\",\n    \"poblacion\": \"Madrid\",\n    \"provincia\": \"Madrid\"\n  }\n]\n`\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/nifs\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            [
                              {
                                "nif": "B86561412",
                                "entorno": "test",
                                "hacienda": "verifactu",
                                "nombre": "Mi empresa SL",
                                "direccion": "Calle Mayor 15",
                                "cp": "28040",
                                "poblacion": "Madrid",
                                "provincia": "Madrid"
                              },
                              {
                                "nif": "B01345232",
                                "entorno": "prod",
                                "hacienda": "verifactu",
                                "nombre": "Mi otra empresa SL",
                                "direccion": "Gran Vía 22",
                                "cp": "28040",
                                "poblacion": "Madrid",
                                "provincia": "Madrid"
                              }
                            ]
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        [
              {
                ""nif"": ""B86561412"",
                ""entorno"": ""test"",
                ""hacienda"": ""verifactu"",
                ""nombre"": ""Mi empresa SL"",
                ""direccion"": ""Calle Mayor 15"",
                ""cp"": ""28040"",
                ""poblacion"": ""Madrid"",
                ""provincia"": ""Madrid""
              },
              {
                ""nif"": ""B01345232"",
                ""entorno"": ""prod"",
                ""hacienda"": ""verifactu"",
                ""nombre"": ""Mi otra empresa SL"",
                ""direccion"": ""Gran Vía 22"",
                ""cp"": ""28040"",
                ""poblacion"": ""Madrid"",
                ""provincia"": ""Madrid""
              }
            ]
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/nifs", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "[" & vbCrLf & _
                   "  {" & vbCrLf & _
                   "    ""nif"": ""B86561412""," & vbCrLf & _
                   "    ""entorno"": ""test""," & vbCrLf & _
                   "    ""hacienda"": ""verifactu""," & vbCrLf & _
                   "    ""nombre"": ""Mi empresa SL""," & vbCrLf & _
                   "    ""direccion"": ""Calle Mayor 15""," & vbCrLf & _
                   "    ""cp"": ""28040""," & vbCrLf & _
                   "    ""poblacion"": ""Madrid""," & vbCrLf & _
                   "    ""provincia"": ""Madrid""" & vbCrLf & _
                   "  }," & vbCrLf & _
                   "  {" & vbCrLf & _
                   "    ""nif"": ""B01345232""," & vbCrLf & _
                   "    ""entorno"": ""prod""," & vbCrLf & _
                   "    ""hacienda"": ""verifactu""," & vbCrLf & _
                   "    ""nombre"": ""Mi otra empresa SL""," & vbCrLf & _
                   "    ""direccion"": ""Gran Vía 22""," & vbCrLf & _
                   "    ""cp"": ""28040""," & vbCrLf & _
                   "    ""poblacion"": ""Madrid""," & vbCrLf & _
                   "    ""provincia"": ""Madrid""" & vbCrLf & _
                   "  }" & vbCrLf & _
                   "]"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      requestBody:
        content:
          application/json:
            schema:
              type: array
              minItems: 1
              maxItems: 400
              items:
                type: object
                required:
                  - nif
                  - entorno
                  - nombre
                properties:
                  nif:
                    description: |
                      NIF. En el array de NIFs, no puede haber duplicados. Tampoco se podrán intentar añadir NIFs que ya se han añadido previamente,
                      incluso si están desactivados. Finalmente, se comprobará el que el formato del NIF es el correcto, pero no que el NIF está
                      registrado en la agencia tributaria. Se dispone de un endpoint específico para ello y se recomienda hacerlo antes de intentar
                      añadir un NIF.
                    type: string
                  nombre:
                    description: Nombre y apellidos o razón social del NIF.
                    type: string
                  entorno:
                    description: |
                      Entorno al que está vinculado el NIF. Los valores posibles son:
                      <ol style="list-style-type: disc">
                        <li>test: se utilizan para enviar facturas al entorno de pruebas de la administración y son gratuitos.</li>
                        <li>
                          prod: se utilizan para enviar facturas al entorno de producción de la administración y se abonará
                          la cantidad correspondiente en el momento de la creación.
                        </li>
                      </ol>
                    type: string
                    enum:
                      - test
                      - prod
                  hacienda:
                    description: |
                      Hacienda a la que estaré vinculado el NIF. En caso de no incluirlo, se asumirá la hacienda `verifactu`. Los valores posibles son:
                      <ol style="list-style-type: disc">
                        <li>verifactu</li>
                        <li>alava</li>
                        <li>guipuzcoa</li>
                        <li>vizcaya</li>
                      </ol>
                    type: string
                    default: verifactu
                  validar_nif:
                    description: |
                      Parámetro opcional. Indica si se debe validar que el NIF está registrado en la administración antes de añadirlo.
                      Por defecto se tomará como `true` y en caso de que se intente añadir un NIF no registrado, se devolverá un error 400.
                      Se puede desactivar esta opción cuando `entorno=test` y dar de alta NIFs no registrados para hacer pruebas. La administración no aceptará
                      facturas enviadas desde NIFs no registrados, incluso en el entorno de test.
                    type: boolean
                    default: true
                  webhooks:
                    description: |
                      Parámetro opcional. Lista de identificadores de los webhooks a los que estará vinculado el NIF.
                    type: array
                    items:
                      type: string
                  label:
                    description: Parámetro opcional. Etiqueta asociada al NIF para organizarlo y filtrarlo.
                    type: string
                  direccion:
                    description: Dirección del NIF.
                    type: string
                  cp:
                    description: Código postal del NIF.
                    type: string
                  poblacion:
                    description: Población del NIF.
                    type: string
                  provincia:
                    description: Provincia del NIF.
                    type: string
                  persona_fisica:
                    description: |
                      Únicamente permitido para Vizcaya. Indica si el NIF debe presentar el modelo 140 (`true`) o el modelo 240 (`false`).
                      En el sistema Batuz, el modelo 140 es para personas físicas (autónomos), comunidades de bienes y sociedades civiles.
                      Al enviar facturas dentro del modelo 140 se debe incluir el campo `detalle_renta`.
                      Por defecto se tomará como `false`.
                    type: boolean
                    default: false
              example:
                - nif: B86561412
                  entorno: test
                  hacienda: verifactu
                  nombre: Mi empresa SL
                  direccion: Calle Mayor 15
                  cp: "28040"
                  poblacion: Madrid
                  provincia: Madrid
                - nif: B01345232
                  entorno: prod
                  hacienda: verifactu
                  nombre: Mi otra empresa SL
                  direccion: Gran Vía 22
                  cp: "28040"
                  poblacion: Madrid
                  provincia: Madrid
      responses:
        "200":
          description: NIF
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    nif:
                      description: NIF.
                      type: string
                    nombre:
                      description: Nombre y apellidos o razón social del NIF.
                      type: string
                    activo:
                      description: Indica si el NIF está activo o no.
                      type: boolean
                    direccion:
                      description: Dirección del NIF.
                      type: string
                    cp:
                      description: Código postal del NIF.
                      type: string
                    poblacion:
                      description: Población del NIF.
                      type: string
                    provincia:
                      description: Provincia del NIF.
                      type: string
                    fecha_creacion:
                      description: Fecha de creación del NIF.
                      type: string
                    fecha_modificacion:
                      description: Fecha de la última modificación del NIF.
                      type: string
                example:
                  - nif: B86561412
                    nombre: Mi empresa SL
                    hacienda: verifactu
                    webhooks: []
                    activo: true
                    direccion: Calle Mayor 15
                    cp: "28040"
                    poblacion: Madrid
                    provincia: Madrid
                    fecha_creacion: "2025-01-12T00:00:00.000Z"
                    fecha_modificacion: "2025-12-01T00:00:00.000Z"
                  - nif: B01345232
                    nombre: Mi otra empresa SL
                    hacienda: verifactu
                    webhooks: []
                    activo: true
                    direccion: Gran Vía 22
                    cp: "28040"
                    poblacion: Madrid
                    provincia: Madrid
                    fecha_creacion: "2025-01-12T00:00:00.000Z"
                    fecha_modificacion: "2025-12-01T00:00:00.000Z"
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "409":
          description: NIF ya existe
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /nifs/{entorno}/{nif}:
    get:
      summary: Información de NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno del NIF
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: Este endpoint devuelve la información de un NIF concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/test/B86561412' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/test/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/test/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/nifs/test/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/test/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/nifs/test/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/test/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/nifs/test/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/test/B86561412"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/nifResponse"
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    put:
      summary: Modificar NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno del NIF
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: Este endpoint permite modificar la información de un NIF concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl --request PUT 'https://api.verifacti.com/nifs/test/B86561412' \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --header 'Content-Type: application/json' \
            --data-raw '{
              "nombre": "Mi empresa SL",
              "webhooks": ["17067405-8c32-4efe-a7cb-8fad93403997"],
              "direccion": "Calle Mayor 15",
              "cp": "28040",
              "poblacion": "Madrid",
              "provincia": "Madrid",
            }'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/test/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            }
            data = {
              'nombre': 'Mi empresa SL',
              'webhooks': ['17067405-8c32-4efe-a7cb-8fad93403997'],
              'direccion': 'Calle Mayor 15',
              'cp': '28040',
              'poblacion': 'Madrid',
              'provincia': 'Madrid',
            }
            response = requests.put(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/test/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            };
            const data = {
              'nombre': 'Mi empresa SL',
              'webhooks': ['17067405-8c32-4efe-a7cb-8fad93403997'],
              'direccion': 'Calle Mayor 15',
              'cp': '28040',
              'poblacion': 'Madrid',
              'provincia': 'Madrid',
            };
            fetch(url, { headers, method: 'PUT', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = {
              'nombre': 'Mi empresa SL',
              'webhooks': ['17067405-8c32-4efe-a7cb-8fad93403997'],
              'direccion': 'Calle Mayor 15',
              'cp': '28040',
              'poblacion': 'Madrid',
              'provincia': 'Madrid',
            };

            const response = await axios.put("https://api.verifacti.com/nifs/test/B86561412", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/test/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            {
              "nombre": "Mi empresa SL",
              "webhooks": ["17067405-8c32-4efe-a7cb-8fad93403997"],
              "direccion": "Calle Mayor 15",
              "cp": "28040",
              "poblacion": "Madrid",
              "provincia": "Madrid",
            }
            JSON;

            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n{\n  \"nombre\": \"Mi empresa SL\",\n  \"webhooks\": [\"17067405-8c32-4efe-a7cb-8fad93403997\"],\n  \"direccion\": \"Calle Mayor 15\",\n  \"cp\": \"28040\",\n  \"poblacion\": \"Madrid\",\n  \"provincia\": \"Madrid\",\n}\n`\n\n\treq, err := http.NewRequest(\"PUT\", \"https://api.verifacti.com/nifs/test/B86561412\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            {
                              "nombre": "Mi empresa SL",
                              "webhooks": ["17067405-8c32-4efe-a7cb-8fad93403997"],
                              "direccion": "Calle Mayor 15",
                              "cp": "28040",
                              "poblacion": "Madrid",
                              "provincia": "Madrid",
                            }
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/test/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .PUT(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        {
              ""nombre"": ""Mi empresa SL"",
              ""webhooks"": [""17067405-8c32-4efe-a7cb-8fad93403997""],
              ""direccion"": ""Calle Mayor 15"",
              ""cp"": ""28040"",
              ""poblacion"": ""Madrid"",
              ""provincia"": ""Madrid"",
            }
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PutAsync("https://api.verifacti.com/nifs/test/B86561412", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/test/B86561412"

            oHttp.Open "PUT", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{" & vbCrLf & _
                   "  ""nombre"": ""Mi empresa SL""," & vbCrLf & _
                   "  ""webhooks"": [""17067405-8c32-4efe-a7cb-8fad93403997""]," & vbCrLf & _
                   "  ""direccion"": ""Calle Mayor 15""," & vbCrLf & _
                   "  ""cp"": ""28040""," & vbCrLf & _
                   "  ""poblacion"": ""Madrid""," & vbCrLf & _
                   "  ""provincia"": ""Madrid""," & vbCrLf & _
                   "}"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                nombre:
                  description: Nombre y apellidos o razón social del NIF.
                  type: string
                  example: Mi empresa SL
                direccion:
                  description: Dirección del NIF.
                  type: string
                  example: Calle Mayor 15
                cp:
                  description: Código postal del NIF.
                  type: string
                  example: "28040"
                poblacion:
                  description: Población del NIF.
                  type: string
                  example: Madrid
                provincia:
                  description: Provincia del NIF.
                  type: string
                  example: Madrid
                webhooks:
                  description: |
                    Lista de identificadores de los webhooks a los que estará vinculado el NIF.
                  type: array
                  items:
                    type: string
                    example: 17067405-8c32-4efe-a7cb-8fad93403997
                label:
                  description: Etiqueta asociada al NIF. Enviar una cadena vacía elimina la etiqueta existente.
                  type: string
                  example: Cliente A
      responses:
        "200":
          $ref: "#/components/responses/nifResponse"
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    delete:
      summary: Desactivar NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno del NIF
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: |
        Este endpoint permite desactivar un NIF. Esto significa que ya no se podrán hacer llamadas a nuestra API para enviar facturas
        a la Hacienda correspondiente para el NIF desactivado.

        Dejará de cobrarse lo correspondiente al NIF desactivado en caso de que se trate de un NIF en el entorno de producción. Cualquier NIF
        desactivado puede reactivarse en cualquier momento para seguir enviando facturas a la Hacienda correspondiente.

        &nbsp;

        <span style="color: red">IMPORTANTE</span>: Al desactivar un NIF, <u><strong>se borrarán los registros de facturación</strong></u> de dicho NIF 30 días después de haberlo desactivado.
        Si se reactiva antes de dicho período, entonces no se perderán los registros de facturación. Incluso aunque se borren los datos de facturación, se puede reactivar
        el NIF en cualquier momento y se podrán enviar facturas sin romper el encadenamiento. Recordamos que existen los endpoints de exportar XMLs en caso de querer
        conservar los datos de facturación.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/test/B86561412' \
            --request DELETE \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/test/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.delete(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/test/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'DELETE' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.delete("https://api.verifacti.com/nifs/test/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/test/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.verifacti.com/nifs/test/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/test/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .DELETE()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.DeleteAsync("https://api.verifacti.com/nifs/test/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/test/B86561412"

            oHttp.Open "DELETE", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "403":
          description: NIF ya está inactivo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /nifs/{entorno}/{nif}/permanent:
    delete:
      summary: Eliminar NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno del NIF
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: |
        Este endpoint permite eliminar <u><strong>permanentemente</strong></u> un NIF. Se borrará toda la información asociada al NIF, incluyendo los registros de facturación,
        de manera inmediata y permanente. Esto no incluye el modelo de representación.

        &nbsp;

        Dejará de cobrarse lo correspondiente al NIF eliminado en caso de que se trate de un NIF en el entorno de producción. Cualquier NIF
        eliminado no podrá reactivarse ni utilizarse para enviar facturas a la Hacienda correspondiente. Sin embargo, se podrá crear de nuevo
        el NIF pero se tratará como un NIF completamente nuevo. Dicho nuevo NIF tendrá su propia cadena de facturación independiente del NIF eliminado.

        &nbsp;

        <span style="color: red">IMPORTANTE</span>: Al eliminar un NIF, <u><strong>se borrarán los registros de facturación</strong></u> asociados.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/test/B86561412/permanent' \
            --request DELETE \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/test/B86561412/permanent'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.delete(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/test/B86561412/permanent';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'DELETE' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.delete("https://api.verifacti.com/nifs/test/B86561412/permanent", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/test/B86561412/permanent";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.verifacti.com/nifs/test/B86561412/permanent\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/test/B86561412/permanent"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .DELETE()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.DeleteAsync("https://api.verifacti.com/nifs/test/B86561412/permanent");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/test/B86561412/permanent"

            oHttp.Open "DELETE", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /nifs/activate/{entorno}/{nif}:
    put:
      summary: Activar NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno del NIF
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: |
        Este endpoint permite activar un NIF que ha sido desactivado previamente.

        &nbsp;

        <span style="color: red">IMPORTANTE</span>: Al activar un NIF de producción cuya fecha `pagado_hasta` sea anterior a la fecha actual,
        se abonará la cantidad correspondiente inmediatamente y se generará la factura correspondiente.
        Ésta puede consultarse con el la plataforma, en la sección de facturación. Para aquellos NIFs de producción cuya fecha `pagado_hasta`
        sea posterior a la fecha actual, no se cobrará nada, ya que ya se ha pagado por el para el periodo actual.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/activate/test/B86561412' \
            --request PUT \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/activate/test/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.put(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/activate/test/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'PUT' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.put("https://api.verifacti.com/nifs/activate/test/B86561412", null, {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/activate/test/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"PUT\", \"https://api.verifacti.com/nifs/activate/test/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/activate/test/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .PUT(HttpRequest.BodyPublishers.noBody())
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.PutAsync("https://api.verifacti.com/nifs/activate/test/B86561412", null);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/activate/test/B86561412"

            oHttp.Open "PUT", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "403":
          description: NIF ya está activo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /nifs/keys/{entorno}/{nif}:
    get:
      summary: API key de NIF
      tags:
        - NIFs
      parameters:
        - in: path
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          required: true
          description: Entorno
          example: test
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: |
        Este endpoint devuelve la API key de un NIF concreto y en un entorno concreto. Con esta API key se pueden hacer llamadas a nuestra API de Verifactu o TicketBai,
        según corresponda, para enviar facturas a la agencia tributaria. En caso de que el NIF esté desactivado, se devuelve un error 404.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/keys/test/B86561412' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/keys/test/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/keys/test/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/nifs/keys/test/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/keys/test/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/nifs/keys/test/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/keys/test/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/nifs/keys/test/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/keys/test/B86561412"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_key:
                    description: API key para el NIF y el entorno correspondientes.
                    type: string
                    example: B86561412
        "404":
          description: NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /nifs/validar:
    post:
      summary: Validar NIF en la AEAT
      tags:
        - Validación
      description: |
        Este endpoint permite validar que un NIF de una persona física o jurídica está identificado en la agencia tributaria. Este endpoint
        realiza una consulta al servicio que la agencia tributaria tiene para esta finalidad.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - nif
              properties:
                nif:
                  description: NIF de la persona física o jurídica sobre la que se quiere efectuar la consulta de verificación.
                  type: string
                  example: B86561412
                nombre:
                  type: string
                  example: Mi empresa SL
                  description: |
                    Apellidos y nombre de la persona física o razón social de la persona jurídica sobre la que se
                    quiere efectuar la consulta de verificación. Obligatorio para personas físicas. Opcional en personas jurídicas.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/validar' \
            --request POST \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --data-raw '{"nif": "B86561412", "nombre": "Mi empresa SL"}'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/validar'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            data = {
              'nif': 'B86561412',
              'nombre': 'Mi empresa SL'
            }
            response = requests.post(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/validar';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            const data = {
              'nif': 'B86561412',
              'nombre': 'Mi empresa SL'
            };
            fetch(url, { headers, method: 'POST', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = {
              'nif': 'B86561412',
              'nombre': 'Mi empresa SL'
            };

            const response = await axios.post("https://api.verifacti.com/nifs/validar", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/validar";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            {"nif": "B86561412", "nombre": "Mi empresa SL"}
            JSON;

            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n{\"nif\": \"B86561412\", \"nombre\": \"Mi empresa SL\"}\n`\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/nifs/validar\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            {"nif": "B86561412", "nombre": "Mi empresa SL"}
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/validar"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        {""nif"": ""B86561412"", ""nombre"": ""Mi empresa SL""}
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/nifs/validar", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/validar"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{""nif"": ""B86561412"", ""nombre"": ""Mi empresa SL""}"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: Respuesta de la AEAT
          content:
            application/json:
              schema:
                type: object
                properties:
                  nif:
                    description: NIF de la persona física o jurídica sobre la que se efectúa la consulta.
                    type: string
                    example: B86561412
                  nombre:
                    description: Apellidos y nombre o razón social del NIF de la persona física o jurídica.
                    type: string
                    example: Mi empresa SL
                  resultado:
                    type: string
                    example: IDENTIFICADO
                    description: |
                      Indica si el NIF está identificado o no. Para el caso de personas físicas existen tres
                      casos posibles:
                        <ol style="list-style-type: disc">
                          <li>
                            IDENTIFICADO: Si el contribuyente se identifica con los datos identificativos aportados.
                            Se devuelven los datos de apellidos y nombre asociados al NIF.
                          </li>
                          <li>
                            NO IDENTIFICADO-SIMILAR: Si el contribuyente no se identifica con los datos identificativos
                            aportados por diferencias menores en los apellidos y nombre. Se devuelven los datos de apellidos
                            y nombre asociados al NIF.
                          </li>
                          <li>
                            NO IDENTIFICADO: Si el contribuyente no se identifica con los datos identificativos aportados.
                          </li>
                        </ol>

                      En el caso de entidades, no existe el resultado NO IDENTIFICADO-SIMILAR pero se añaden estos dos resultados:
                        <ol style="list-style-type: disc">
                          <li>
                            IDENTIFICADO-BAJA: Si el contribuyente se identifica con el NIF aportado y está en estado baja.
                            Se devuelve el NIF actual y su razón social.
                          </li>
                          <li>
                            IDENTIFICADO-REVOCADO: Si el contribuyente se identifica con el NIF aportado y está en estado
                            baja por revocación del NIF. Se devuelve el NIF actual y su razón social.
                          </li>
                        </ol>
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          description: Error interno del servidor o servicio de la AEAT no disponible
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
  /nifs/validar_lotes:
    post:
      summary: Validar NIFs en lote
      tags:
        - Validación
      description: |
        Este endpoint permite validar hasta 20000 NIFs en una única llamada, comprobando si cada NIF de una persona física o jurídica existe.
      requestBody:
        content:
          application/json:
            schema:
              type: array
              minItems: 1
              maxItems: 20000
              items:
                type: object
                description: Cada elemento del array tiene el formato descrito en el endpoint de validar NIF en la AEAT.
              example:
                - nif: B86561412
                  nombre: Mi empresa SL
                - nif: C01345232
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/validar_lotes' \
            --request POST \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --data-raw '[{"nif": "B86561412", "nombre": "Mi empresa SL"}, {"nif": "C01345232"}]'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/validar_lotes'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            data = [
              {'nif': 'B86561412', 'nombre': 'Mi empresa SL'},
              {'nif': 'C01345232'}
            ]
            response = requests.post(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/validar_lotes';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            const data = [
              {'nif': 'B86561412', 'nombre': 'Mi empresa SL'},
              {'nif': 'C01345232'}
            ];
            fetch(url, { headers, method: 'POST', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = [
              {'nif': 'B86561412', 'nombre': 'Mi empresa SL'},
              {'nif': 'C01345232'}
            ];

            const response = await axios.post("https://api.verifacti.com/nifs/validar_lotes", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/validar_lotes";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            [{"nif": "B86561412", "nombre": "Mi empresa SL"}, {"nif": "C01345232"}]
            JSON;

            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n[{\"nif\": \"B86561412\", \"nombre\": \"Mi empresa SL\"}, {\"nif\": \"C01345232\"}]\n`\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/nifs/validar_lotes\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            [{"nif": "B86561412", "nombre": "Mi empresa SL"}, {"nif": "C01345232"}]
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/validar_lotes"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        [{""nif"": ""B86561412"", ""nombre"": ""Mi empresa SL""}, {""nif"": ""C01345232""}]
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/nifs/validar_lotes", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/validar_lotes"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "[{""nif"": ""B86561412"", ""nombre"": ""Mi empresa SL""}, {""nif"": ""C01345232""}]"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: Respuesta de la AEAT
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    nif:
                      description: NIF de la persona física o jurídica sobre la que se efectúa la consulta.
                      type: string
                      example: B86561412
                    nombre:
                      description: Apellidos y nombre o razón social del NIF de la persona física o jurídica.
                      type: string
                      example: Mi empresa SL
                    resultado:
                      type: string
                      example: IDENTIFICADO
                      enum:
                        - IDENTIFICADO
                        - NO IDENTIFICADO
                        - NO IDENTIFICADO-SIMILAR
                        - IDENTIFICADO-BAJA
                        - IDENTIFICADO-REVOCADO
                        - ERROR
                      description: |
                        Indica si el NIF está identificado o no. Los valores posibles son:
                        <ol style="list-style-type: disc">
                          <li>IDENTIFICADO: El NIF está identificado con los datos aportados.</li>
                          <li>NO IDENTIFICADO: El NIF no está identificado.</li>
                          <li>NO IDENTIFICADO-SIMILAR: El NIF no está identificado por diferencias menores (solo personas físicas).</li>
                          <li>IDENTIFICADO-BAJA: El NIF está identificado pero en estado de baja (solo entidades).</li>
                          <li>IDENTIFICADO-REVOCADO: El NIF está identificado pero revocado (solo entidades).</li>
                          <li>ERROR: No se ha podido obtener el resultado para este NIF.</li>
                        </ol>
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          description: Error interno del servidor o servicio de la AEAT no disponible
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
  /nifs/validar/vies:
    post:
      summary: Validar IVA en VIES
      tags:
        - Validación
      description: Este endpoint permite validar que un número de IVA intracomunitario se encuentra en el censo VIES.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - codigo_pais
                - iva
              properties:
                codigo_pais:
                  description: Código de país al que pertenece el IVA.
                  type: string
                  example: DE
                iva:
                  description: Número de IVA intracomunitario.
                  type: string
                  example: DE123456789
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/nifs/validar/vies' \
            --request POST \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --data-raw '{"codigo_pais": "DE", "iva": "DE123456789"}'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/nifs/validar/vies'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            data = {
              'codigo_pais': 'DE',
              'iva': 'DE123456789'
            }
            response = requests.post(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/nifs/validar/vies';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            const data = {
              'codigo_pais': 'DE',
              'iva': 'DE123456789'
            };
            fetch(url, { headers, method: 'POST', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = {
              'codigo_pais': 'DE',
              'iva': 'DE123456789'
            };

            const response = await axios.post("https://api.verifacti.com/nifs/validar/vies", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/nifs/validar/vies";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            {"codigo_pais": "DE", "iva": "DE123456789"}
            JSON;

            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n{\"codigo_pais\": \"DE\", \"iva\": \"DE123456789\"}\n`\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/nifs/validar/vies\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            {"codigo_pais": "DE", "iva": "DE123456789"}
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/nifs/validar/vies"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        {""codigo_pais"": ""DE"", ""iva"": ""DE123456789""}
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/nifs/validar/vies", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/nifs/validar/vies"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{""codigo_pais"": ""DE"", ""iva"": ""DE123456789""}"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: Respuesta del censo VIES
          content:
            application/json:
              schema:
                type: object
                properties:
                  iva:
                    description: Número de IVA intracomunitario sobre el que se realiza la consulta.
                    type: string
                    example: DE123456789
                  resultado:
                    type: string
                    example: IDENTIFICADO
                    description: |
                      Indica si el número de IVA está identificado o no. Esta API devuelve en algunas ocasiones el resultado ERROR API VIES, que ocurre cuando
                      las propias APIs de validación de cada país alcanzan el límite de peticiones. Es un límite global y no es para la IP de Verifacti ni nada
                      por el estilo.
                    enum:
                      - IDENTIFICADO
                      - NO IDENTIFICADO
                      - ERROR API VIES
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /representacion/generar/{nif}:
    post:
      summary: Generar PDF de representación
      tags:
        - Modelo de representación
      parameters:
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF correspondiente al emisor de las facturas
          example: B86561412
      description: |
        Este endpoint permite descargar el documento PDF de otorgamiento de representación para un NIF de Verifactu.
        <strong>No debe modificarse el contenido del documento descargado. Simplemente se debe firmar.</strong>
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                tipo_entidad:
                  description: Tipo de entidad, personas físicas o jurídicas.
                  enum:
                    - fisica
                    - juridica
                  example: juridica
                nombre:
                  type: string
                  description: Obligatorio para personas físicas. Nombre y apellidos del emisor de las facturas.
                municipio:
                  type: string
                  description: Obligatorio para personas físicas. Municipio de residencia del emisor de las facturas.
                calle:
                  type: string
                  description: Obligatorio para personas físicas. Calle de residencia del emisor de las facturas.
                numero:
                  type: string
                  description: Obligatorio para personas físicas. Número de residencia del emisor de las facturas.
                nombre_entidad:
                  type: string
                  description: Obligatorio para personas jurídicas. Nombre de la entidad.
                municipio_entidad:
                  type: string
                  description: Obligatorio para personas jurídicas. Municipio del domicilio social de la entidad.
                calle_entidad:
                  type: string
                  description: Obligatorio para personas jurídicas. Calle del domicilio social de la entidad.
                numero_entidad:
                  type: string
                  description: Obligatorio para personas jurídicas. Número del domicilio social de la entidad.
                nombre_representante:
                  type: string
                  description: Obligatorio para personas jurídicas. Nombre y apellidos del representante de la entidad.
                nif_representante:
                  type: string
                  description: Obligatorio para personas jurídicas. NIF del representante de la entidad.
                municipio_representante:
                  type: string
                  description: Obligatorio para personas jurídicas. Municipio de residencia del representante de la entidad.
                calle_representante:
                  type: string
                  description: Obligatorio para personas jurídicas. Calle de residencia del representante de la entidad.
                numero_representante:
                  type: string
                  description: Obligatorio para personas jurídicas. Número de residencia del representante de la entidad.
              example:
                tipo_entidad: juridica
                nombre_entidad: Mi empresa SL
                municipio_entidad: Madrid
                calle_entidad: Calle Mayor
                numero_entidad: "15"
                nombre_representante: Pablo García Gómez
                nif_representante: 16085921K
                municipio_representante: Madrid
                calle_representante: Gran Vía
                numero_representante: "43"
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/representacion/generar/B86561412' \
            --request POST \
            --header 'Content-Type: application/json' \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --data-raw '{"tipo_entidad": "juridica", "nombre_entidad": "Mi empresa SL", "municipio_entidad": "Madrid", "calle_entidad": "Calle Mayor", "numero_entidad": "15", "nombre_representante": "Pablo García Gómez", "nif_representante": "16085921K", "municipio_representante": "Madrid", "calle_representante": "Gran Vía", "numero_representante": "43"}' \
            --output modelo_representacion.pdf
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/representacion/generar/B86561412'
            headers = {
              'Content-Type': 'application/json',
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            data = {
              'tipo_entidad': 'juridica',
              'nombre_entidad': 'Mi empresa SL',
              'municipio_entidad': 'Madrid',
              'calle_entidad': 'Calle Mayor',
              'numero_entidad': '15',
              'nombre_representante': 'Pablo García Gómez',
              'nif_representante': '16085921K',
              'municipio_representante': 'Madrid',
              'calle_representante': 'Gran Vía',
              'numero_representante': '43'
            }
            response = requests.post(url, headers=headers, json=data)
            with open('modelo_representacion.pdf', 'wb') as f:
              f.write(response.content)
        - lang: JavaScript
          label: JavaScript
          source: |
            const { writeFile } = require('fs').promises;

            const url = 'https://api.verifacti.com/representacion/generar/B86561412';
            const headers = {
              'Content-Type': 'application/json',
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            const data = {
              'tipo_entidad': 'juridica',
              'nombre_entidad': 'Mi empresa SL',
              'municipio_entidad': 'Madrid',
              'calle_entidad': 'Calle Mayor',
              'numero_entidad': '15',
              'nombre_representante': 'Pablo García Gómez',
              'nif_representante': '16085921K',
              'municipio_representante': 'Madrid',
              'calle_representante': 'Gran Vía',
              'numero_representante': '43'
            };
            fetch(url, {
              method: 'POST',
              headers,
              body: JSON.stringify(data)
            })
              .then(response => response.blob())
              .then(blob => writeFile('modelo_representacion.pdf', blob))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");
            const fs = require("fs");

            const data = {
              "tipo_entidad": "juridica",
              "nombre_entidad": "Mi empresa SL",
              "municipio_entidad": "Madrid",
              "calle_entidad": "Calle Mayor",
              "numero_entidad": "15",
              "nombre_representante": "Pablo García Gómez",
              "nif_representante": "16085921K",
              "municipio_representante": "Madrid",
              "calle_representante": "Gran Vía",
              "numero_representante": "43"
            };

            const response = await axios.post("https://api.verifacti.com/representacion/generar/B86561412", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              },
              responseType: "arraybuffer"
            });

            fs.writeFileSync("modelo_representacion.pdf", response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/representacion/generar/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $body = json_encode([
                "tipo_entidad" => "juridica",
                "nombre_entidad" => "Mi empresa SL",
                "municipio_entidad" => "Madrid",
                "calle_entidad" => "Calle Mayor",
                "numero_entidad" => "15",
                "nombre_representante" => "Pablo García Gómez",
                "nif_representante" => "16085921K",
                "municipio_representante" => "Madrid",
                "calle_representante" => "Gran Vía",
                "numero_representante" => "43"
            ]);

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            file_put_contents("modelo_representacion.pdf", $response);
            echo "HTTP Status: " . $httpCode . "\n";
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\tdata := map[string]string{\n\t\t\"tipo_entidad\": \"juridica\",\n\t\t\"nombre_entidad\": \"Mi empresa SL\",\n\t\t\"municipio_entidad\": \"Madrid\",\n\t\t\"calle_entidad\": \"Calle Mayor\",\n\t\t\"numero_entidad\": \"15\",\n\t\t\"nombre_representante\": \"Pablo García Gómez\",\n\t\t\"nif_representante\": \"16085921K\",\n\t\t\"municipio_representante\": \"Madrid\",\n\t\t\"calle_representante\": \"Gran Vía\",\n\t\t\"numero_representante\": \"43\",\n\t}\n\tjsonBody, _ := json.Marshal(data)\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/representacion/generar/B86561412\", bytes.NewBuffer(jsonBody))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tos.WriteFile(\"modelo_representacion.pdf\", respBody, 0644)\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.file.Files;
            import java.nio.file.Path;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = "{\"tipo_entidad\": \"juridica\", \"nombre_entidad\": \"Mi empresa SL\", \"municipio_entidad\": \"Madrid\", \"calle_entidad\": \"Calle Mayor\", \"numero_entidad\": \"15\", \"nombre_representante\": \"Pablo García Gómez\", \"nif_representante\": \"16085921K\", \"municipio_representante\": \"Madrid\", \"calle_representante\": \"Gran Vía\", \"numero_representante\": \"43\"}";

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/representacion/generar/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<byte[]> response = client.send(request,
                        HttpResponse.BodyHandlers.ofByteArray());

                    Files.write(Path.of("modelo_representacion.pdf"), response.body());
                    System.out.println(response.statusCode());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.IO;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"{""tipo_entidad"": ""juridica"", ""nombre_entidad"": ""Mi empresa SL"", ""municipio_entidad"": ""Madrid"", ""calle_entidad"": ""Calle Mayor"", ""numero_entidad"": ""15"", ""nombre_representante"": ""Pablo García Gómez"", ""nif_representante"": ""16085921K"", ""municipio_representante"": ""Madrid"", ""calle_representante"": ""Gran Vía"", ""numero_representante"": ""43""}";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/representacion/generar/B86561412", content);

                    var responseBytes = await response.Content.ReadAsByteArrayAsync();
                    File.WriteAllBytes("modelo_representacion.pdf", responseBytes);
                    Console.WriteLine($"Status: {response.StatusCode}");
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/representacion/generar/B86561412"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{""tipo_entidad"": ""juridica"", ""nombre_entidad"": ""Mi empresa SL"", ""municipio_entidad"": ""Madrid"", ""calle_entidad"": ""Calle Mayor"", ""numero_entidad"": ""15"", ""nombre_representante"": ""Pablo García Gómez"", ""nif_representante"": ""16085921K"", ""municipio_representante"": ""Madrid"", ""calle_representante"": ""Gran Vía"", ""numero_representante"": ""43""}"

            oHttp.send sBody

            Debug.Print "Status: " & oHttp.Status

            Set oHttp = Nothing
      responses:
        "200":
          description: Documento PDF de otorgamiento de representación
          headers:
            Content-Disposition:
              description: Encabezado Content-Disposition
              schema:
                type: string
                example: attachment; filename="modelo_representacion.pdf"
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /representacion/enviar/{nif}:
    post:
      summary: Enviar PDF firmado
      tags:
        - Modelo de representación
      parameters:
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF correspondiente al emisor de las facturas
          example: B86561412
      description: |
        Mediante este endpoint se envía el documento PDF de otorgamiento de representación para un NIF de Verifactu.
        Una vez enviado un documento de representación que se haya aceptado, no podrá ser reenviado.
      requestBody:
        description: The PDF file to be processed
        required: true
        content:
          multipart/form-data:
            schema:
              type: string
              format: binary
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/representacion/enviar/B86561412' \
            --request POST \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --form 'file=@"/ruta/pdf.pdf"'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/representacion/enviar/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            with open('/ruta/pdf.pdf', 'rb') as pdf_file:
              files = {
                  'file': ('pdf.pdf', pdf_file, 'application/pdf')
              }
              response = requests.post(url, headers=headers, files=files)
        - lang: JavaScript
          label: JavaScript
          source: |
            const fs = require('fs').promises;

            (async () => {
              try {
                const fileBuffer = await fs.readFile('/ruta/archivo.pdf');
                const pdfBlob = new Blob([fileBuffer], { type: 'application/pdf' });
                const form = new FormData();
                form.append('file', pdfBlob, 'archivo.pdf');

                return res = await fetch(
                  'https://api.verifacti.com/representacion/enviar/B86561412',
                  {
                    method: 'POST',
                    headers: {
                      'Authorization': 'Bearer <USER_API_KEY>'
                    },
                    body: form,
                  }
                );

              } catch (err) {
                console.error('Upload error:', err);
              }
            })();
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");
            const FormData = require("form-data");
            const fs = require("fs");

            const form = new FormData();
            form.append("file", fs.createReadStream("/ruta/pdf.pdf"), {
              filename: "pdf.pdf",
              contentType: "application/pdf"
            });

            const response = await axios.post("https://api.verifacti.com/representacion/enviar/B86561412", form, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                ...form.getHeaders()
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/representacion/enviar/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, [
                'file' => new CURLFile('/ruta/pdf.pdf', 'application/pdf', 'pdf.pdf')
            ]);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\tvar buf bytes.Buffer\n\twriter := multipart.NewWriter(&buf)\n\tfile, err := os.Open(\"/ruta/pdf.pdf\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer file.Close()\n\tpart, err := writer.CreateFormFile(\"file\", \"pdf.pdf\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tio.Copy(part, file)\n\twriter.Close()\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/representacion/enviar/B86561412\", &buf)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", writer.FormDataContentType())\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.io.IOException;
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.file.Files;
            import java.nio.file.Path;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();
                    String boundary = "----FormBoundary" + System.currentTimeMillis();
                    Path filePath = Path.of("/ruta/pdf.pdf");
                    byte[] fileBytes = Files.readAllBytes(filePath);

                    String body = "--" + boundary + "\r\n"
                        + "Content-Disposition: form-data; name=\"file\"; filename=\"pdf.pdf\"\r\n"
                        + "Content-Type: application/pdf\r\n\r\n";
                    String end = "\r\n--" + boundary + "--\r\n";

                    byte[] bodyBytes = body.getBytes();
                    byte[] endBytes = end.getBytes();
                    byte[] requestBody = new byte[bodyBytes.length + fileBytes.length + endBytes.length];
                    System.arraycopy(bodyBytes, 0, requestBody, 0, bodyBytes.length);
                    System.arraycopy(fileBytes, 0, requestBody, bodyBytes.length, fileBytes.length);
                    System.arraycopy(endBytes, 0, requestBody, bodyBytes.length + fileBytes.length, endBytes.length);

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/representacion/enviar/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "multipart/form-data; boundary=" + boundary)
                        .POST(HttpRequest.BodyPublishers.ofByteArray(requestBody))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.IO;
            using System.Net.Http;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    using var form = new MultipartFormDataContent();
                    var fileContent = new ByteArrayContent(File.ReadAllBytes("/ruta/pdf.pdf"));
                    fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
                    form.Add(fileContent, "file", "pdf.pdf");

                    var response = await client.PostAsync("https://api.verifacti.com/representacion/enviar/B86561412", form);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/representacion/enviar/B86561412"

            ' Para subir archivos en VB6, se recomienda usar cURL desde la línea de comandos
            ' o utilizar una librería externa que soporte multipart/form-data.
            ' Ejemplo usando cURL desde VB6:
            Shell "curl -X POST " & sUrl & " -H ""Authorization: Bearer <API_KEY>"" -F ""file=@C:\ruta\pdf.pdf"""

            Set oHttp = Nothing
      responses:
        "200":
          description: PDF enviado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  estado:
                    description: |
                      Estado de la representación. Los valores posibles son:
                      <ul style="list-style-type: disc">
                        <li>Correcto: El modelo de representación se ha recibido y se ha validado correctamente.</li>
                        <li>Rechazado: El modelo de representación ha sido recibido pero no se ha podido validar.</li>
                        <li>Inexistente: No se ha recibido el modelo de representación firmado.</li>
                      </ul>
                    enum:
                      - Correcto
                      - Rechazado
                      - Inexistente
                    type: string
                  error:
                    description: Mensaje de error cuando estado=Rechazado
                    type: string
                example:
                  estado: Correcto
        "400":
          description: PDF no enviado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    description: Mensaje de error
                    type: string
                    example: Falta adjuntar fichero PDF
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          description: Error interno del servidor o fallo al procesar el PDF
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
  /representacion/cancelar/{nif}:
    put:
      summary: Cancelar PDF firmado
      tags:
        - Modelo de representación
      parameters:
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF correspondiente al emisor de las facturas
          example: B86561412
      description: |
        Mediante este endpoint se cancela el documento PDF de otorgamiento de representación para un NIF de Verifactu.
        Si se cancela el documento de representación, no se podrán enviar facturas al entorno de producción de la AEAT para ese NIF.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/representacion/cancelar/B86561412' \
            --request PUT \
            --header 'Content-Type: application/json' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/representacion/cancelar/B86561412'
            headers = {
              'Content-Type': 'application/json',
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.put(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/representacion/cancelar/B86561412';
            const headers = {
              'Content-Type': 'application/json',
              'Authorization': 'Bearer <USER_API_KEY>'
            };

            return res = await fetch(url, {
              method: 'PUT',
              headers: headers,
            });
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.put("https://api.verifacti.com/representacion/cancelar/B86561412", null, {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/representacion/cancelar/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"PUT\", \"https://api.verifacti.com/representacion/cancelar/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/representacion/cancelar/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .PUT(HttpRequest.BodyPublishers.noBody())
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.PutAsync("https://api.verifacti.com/representacion/cancelar/B86561412", null);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/representacion/cancelar/B86561412"

            oHttp.Open "PUT", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: PDF cancelado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  estado:
                    description: Estado de la representación
                    type: string
                example:
                  estado: Cancelado
        "404":
          description: Modelo de representación no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    description: Representación no encontrada
                    type: string
                    example: Representación no encontrada
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          description: Error interno del servidor al procesar la cancelación
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
  /representacion/descargar/{nif}:
    get:
      summary: Descargar PDF firmado
      tags:
        - Modelo de representación
      parameters:
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF correspondiente al NIF emisor de las facturas
          example: B86561412
      description: |
        Mediante este endpoint se puede descargar el documento PDF de otorgamiento de representación para un NIF de Verifactu firmado.
        Este endpoint es exclusivo para los NIFs de Verifactu.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/representacion/descargar/B86561412' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/representacion/descargar/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/representacion/descargar/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'GET' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/representacion/descargar/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/representacion/descargar/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/representacion/descargar/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/representacion/descargar/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/representacion/descargar/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/representacion/descargar/B86561412"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: PDF descargado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    description: URL donde se encuentra alojado el PDF. Esta URL tiene una caducidad de 15 minutos.
                    type: string
                    example: https://bucket.com/B86561412
        "404":
          description: PDF no encontrado para el NIF indicado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /representacion/estado/{nif}:
    get:
      summary: Estado de representación
      tags:
        - Modelo de representación
      parameters:
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF correspondiente al emisor de las facturas
          example: B86561412
      description: Mediante este endpoint se puede obtener el estado de la representación para un NIF.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/representacion/estado/B86561412' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/representacion/estado/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/representacion/estado/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'GET' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/representacion/estado/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/representacion/estado/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/representacion/estado/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/representacion/estado/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/representacion/estado/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/representacion/estado/B86561412"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: PDF enviado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  estado:
                    description: |
                      Estado de la representación. Los valores posibles son:
                      <ul style="list-style-type: disc">
                        <li>Correcto: El modelo de representación se ha recibido y se ha validado correctamente.</li>
                        <li>Rechazado: El modelo de representación ha sido recibido pero no se ha podido validar.</li>
                        <li>Inexistente: No se ha recibido el modelo de representación firmado.</li>
                      </ul>
                    enum:
                      - Correcto
                      - Rechazado
                      - Inexistente
                    type: string
                  error:
                    description: Mensaje de error cuando estado=Rechazado
                    type: string
                example:
                  estado: Correcto
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /webhooks:
    get:
      summary: Listar webhooks
      tags:
        - Webhooks
      description: |
        Este endpoint devuelve una lista de todos los webhooks configurados. Por defecto, devuelve tanto los activos como los inactivos en ambos entornos
        aunque permite filtrar solamente los activos o inactivos y el entorno.
      parameters:
        - in: query
          name: entorno
          schema:
            type: string
            enum:
              - test
              - prod
          description: Parámetro que permite filtrar los webhooks dependiendo del entorno. En caso de que no se incluya, se devolverán todos los webhooks.
          example: test
        - in: query
          name: activos
          schema:
            type: boolean
          description: Parámetro que permite filtrar los webhooks dependiendo de si están activos o inactivos. En caso de que no se incluya, se devolverán todos los webhooks.
          example: true
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/webhooks?entorno=test&activos=true' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks?entorno=test&activos=true'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks?entorno=test&activos=true';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/webhooks?entorno=test&activos=true", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks?entorno=test&activos=true";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/webhooks?entorno=test&activos=true\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks?entorno=test&activos=true"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/webhooks?entorno=test&activos=true");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks?entorno=test&activos=true"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          description: Lista de webhooks
          content:
            application/json:
              schema:
                type: array
                items:
                  properties:
                    id:
                      description: Identificador del webhook.
                      type: string
                    url:
                      description: URL a la que se hará la llamada cuando se dispare el webhook.
                      type: string
                    entorno:
                      description: Entorno del webhook. Puede ser "test" o "prod".
                      type: string
                    activo:
                      description: Indica si el webhook está activo o no.
                      type: boolean
                    nifs:
                      type: array
                      description: |
                        Lista de NIFs. Cuando se envían registros de facturación para cualquiera de estos NIFs, se dispara el webhook con el resultado
                        de hacienda una vez obtenido.
                      items:
                        type: string
                example:
                  - id: 17067405-8c32-4efe-a7cb-8fad93403997
                    url: https://api.webdelcliente.com/webhook
                    entorno: test
                    activo: true
                    nifs:
                      - B12345678
                      - B87654321
                  - id: 17067405-8c32-4efe-a7cb-8fad93403997
                    url: https://api.otraweb.com/webhook
                    entorno: test
                    activo: true
                    nifs:
                      - C12345678
        "400":
          description: Parámetros de consulta inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    post:
      summary: Añadir webhook
      tags:
        - Webhooks
      description: Mediante este endpoint se puede registrar un webhook.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl --request POST 'https://api.verifacti.com/webhooks' \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --header 'Content-Type: application/json' \
            --data-raw '{
              "url": "https://api.webdelcliente.com/webhook",
              "entorno": "test",
              "secret": "mi-secreto",
              "nifs": [
                "B86561412",
                "B01345232"
              ]
            }'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            }
            data = {
              'url': 'https://api.webdelcliente.com/webhook',
              'entorno': 'test',
              'secret': 'mi-secreto',
              'nifs': [
                'B86561412',
                'B01345232'
              ]}
            response = requests.post(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            };
            const data = {
              'url': 'https://api.webdelcliente.com/webhook',
              'entorno': 'test',
              'secret': 'mi-secreto',
              'nifs': [
                'B86561412',
                'B01345232'
              ]
            }
            fetch(url, { headers, method: 'POST', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = {
              "url": "https://api.webdelcliente.com/webhook",
              "entorno": "test",
              "secret": "mi-secreto",
              "nifs": [
                "B86561412",
                "B01345232"
              ]
            };

            const response = await axios.post("https://api.verifacti.com/webhooks", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            {
              "url": "https://api.webdelcliente.com/webhook",
              "entorno": "test",
              "secret": "mi-secreto",
              "nifs": [
                "B86561412",
                "B01345232"
              ]
            }
            JSON;

            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n{\n  \"url\": \"https://api.webdelcliente.com/webhook\",\n  \"entorno\": \"test\",\n  \"secret\": \"mi-secreto\",\n  \"nifs\": [\n    \"B86561412\",\n    \"B01345232\"\n  ]\n}\n`\n\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/webhooks\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            {
                              "url": "https://api.webdelcliente.com/webhook",
                              "entorno": "test",
                              "secret": "mi-secreto",
                              "nifs": [
                                "B86561412",
                                "B01345232"
                              ]
                            }
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        {
              ""url"": ""https://api.webdelcliente.com/webhook"",
              ""entorno"": ""test"",
              ""secret"": ""mi-secreto"",
              ""nifs"": [
                ""B86561412"",
                ""B01345232""
              ]
            }
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PostAsync("https://api.verifacti.com/webhooks", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{" & vbCrLf & _
                   "  ""url"": ""https://api.webdelcliente.com/webhook""," & vbCrLf & _
                   "  ""entorno"": ""test""," & vbCrLf & _
                   "  ""secret"": ""mi-secreto""," & vbCrLf & _
                   "  ""nifs"": [" & vbCrLf & _
                   "    ""B86561412""," & vbCrLf & _
                   "    ""B01345232""" & vbCrLf & _
                   "  ]" & vbCrLf & _
                   "}"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - url
                - entorno
              properties:
                url:
                  description: URL a la que se hará la llamada cuando se dispare el webhook.
                  type: string
                entorno:
                  description: Entorno del webhook. Puede ser "test" o "prod".
                  type: string
                  enum:
                    - test
                    - prod
                secret:
                  description: |
                    Parámetro opcional. Una clave secreta que se comparte entre nuestra API y el receptor del webhook. Se utiliza para generar la
                    firma HMAC que acompaña a cada notificación. Al recibir un webhook, el receptor puede usar esta clave para recalcular la firma del
                    mensaje y compararla con la firma proporcionada en el header `X-Webhook-Signature`. Si ambas firmas coinciden, se confirma que el
                    mensaje es auténtico y no ha sido modificado.
                nifs:
                  description: |
                    Lista de NIFs. Cuando se envíen registros de facturación para cualquiera de estos NIFs, se disparará el webhook con el resultado
                    de hacienda una vez obtenido. Dichos NIFs debern estar dados de alta en el entorno en que se está creando el webhook.
              example:
                url: https://api.webdelcliente.com/webhook
                entorno: test
                secret: mi-secreto
                nifs:
                  - B86561412
                  - B01345232
      responses:
        "200":
          $ref: "#/components/responses/webhookResponse"
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "409":
          description: Webhook ya existe con esa URL
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /webhooks/{webhook_id}:
    get:
      summary: Información de webhook
      tags:
        - Webhooks
      parameters:
        - in: path
          name: webhook_id
          schema:
            type: string
          required: true
          description: Identificador del webhook
          example: 17067405-8c32-4efe-a7cb-8fad93403997
      description: Este endpoint devuelve la información de un webhook concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997' \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.get(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.get("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"GET\", \"https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .GET()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.GetAsync("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"

            oHttp.Open "GET", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/webhookResponse"
        "404":
          description: Webhook no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    put:
      summary: Modificar webhook
      tags:
        - Webhooks
      parameters:
        - in: path
          name: webhook_id
          schema:
            type: string
          required: true
          description: Identificador del webhook
          example: 17067405-8c32-4efe-a7cb-8fad93403997
      description: Este endpoint permite modificar un webhook concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl --request PUT 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997' \
            --header 'Authorization: Bearer <USER_API_KEY>' \
            --header 'Content-Type: application/json' \
            --data-raw '{
              "url": "https://api.webdelcliente.com/webhook",
              "secret": "mi-secreto",
              "nifs": [
                "B86561412",
                "B01345232"
              ]
            }'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            }
            data = {
              'url': 'https://api.webdelcliente.com/webhook',
              'secret': 'mi-secreto',
              'nifs': [
                'B86561412',
                'B01345232'
              ]
            }
            response = requests.put(url, headers=headers, json=data)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>',
              'Content-Type': 'application/json'
            };
            const data = {
              'url': 'https://api.webdelcliente.com/webhook',
              'secret': 'mi-secreto',
              'nifs': [
                'B86561412',
                'B01345232'
              ]
            };
            fetch(url, { headers, method: 'PUT', body: JSON.stringify(data) })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const data = {
              'url': 'https://api.webdelcliente.com/webhook',
              'secret': 'mi-secreto',
              'nifs': [
                'B86561412',
                'B01345232'
              ]
            };

            const response = await axios.put("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997", data, {
              headers: {
                "Authorization": "Bearer <API_KEY>",
                "Content-Type": "application/json"
              }
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997";

            $headers = [
                "Authorization: Bearer <API_KEY>",
                "Content-Type: application/json"
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            $body = <<<'JSON'
            {
              "url": "https://api.webdelcliente.com/webhook",
              "secret": "mi-secreto",
              "nifs": [
                "B86561412",
                "B01345232"
              ]
            }
            JSON;

            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc main() {\n\tbody := `\n{\n  \"url\": \"https://api.webdelcliente.com/webhook\",\n  \"secret\": \"mi-secreto\",\n  \"nifs\": [\n    \"B86561412\",\n    \"B01345232\"\n  ]\n}\n`\n\n\treq, err := http.NewRequest(\"PUT\", \"https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997\", strings.NewReader(body))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    String body = """
                            {
                              "url": "https://api.webdelcliente.com/webhook",
                              "secret": "mi-secreto",
                              "nifs": [
                                "B86561412",
                                "B01345232"
                              ]
                            }
                            """;

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .header("Content-Type", "application/json")
                        .PUT(HttpRequest.BodyPublishers.ofString(body))
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var body = @"
                        {
              ""url"": ""https://api.webdelcliente.com/webhook"",
              ""secret"": ""mi-secreto"",
              ""nifs"": [
                ""B86561412"",
                ""B01345232""
              ]
            }
                    ";

                    var content = new StringContent(body, Encoding.UTF8, "application/json");

                    var response = await client.PutAsync("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997", content);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"

            oHttp.Open "PUT", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"
            oHttp.setRequestHeader "Content-Type", "application/json"

            Dim sBody As String
            sBody = "{" & vbCrLf & _
                   "  ""url"": ""https://api.webdelcliente.com/webhook""," & vbCrLf & _
                   "  ""secret"": ""mi-secreto""," & vbCrLf & _
                   "  ""nifs"": [" & vbCrLf & _
                   "    ""B86561412""," & vbCrLf & _
                   "    ""B01345232""" & vbCrLf & _
                   "  ]" & vbCrLf & _
                   "}"

            oHttp.send sBody

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: URL a la que se hará la llamada cuando se dispare el webhook.
                  example: https://api.webdelcliente.com/webhook
                secret:
                  type: string
                  description: Clave para generar la firma HMAC.
                  example: mi-secreto
                activo:
                  type: boolean
                  description: Indica si el webhook estará activo o no.
                  example: true
                nifs:
                  type: array
                  description: |
                    Lista de NIFs. Cuando se envíen registros de facturación para cualquiera de estos NIFs, se disparará el webhook con el resultado
                    de hacienda una vez obtenido. Dichos NIFs debern estar dados de alta en el entorno del webhook.
                  items:
                    type: string
                    example:
                      - B86561412
                      - B01345232
      responses:
        "200":
          $ref: "#/components/responses/webhookResponse"
        "400":
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "404":
          description: Webhook no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "409":
          description: URL de webhook en conflicto con otro existente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    delete:
      summary: Eliminar webhook
      tags:
        - Webhooks
      parameters:
        - in: path
          name: webhook_id
          schema:
            type: string
          required: true
          description: Identificador del webhook
          example: 17067405-8c32-4efe-a7cb-8fad93403997
      description: Este endpoint permite eliminar un webhook concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997' \
            --request DELETE \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.delete(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'DELETE' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.delete("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .DELETE()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.DeleteAsync("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997"

            oHttp.Open "DELETE", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "404":
          description: Webhook no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
  /webhooks/{webhook_id}/nifs/{nif}:
    post:
      summary: Asociar NIF a webhook
      tags:
        - Webhooks
      parameters:
        - in: path
          name: webhook_id
          schema:
            type: string
          required: true
          description: Identificador del webhook
          example: 17067405-8c32-4efe-a7cb-8fad93403997
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: Este endpoint permite asociar un NIF concreto a un webhook concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412' \
            --request POST \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.post(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'POST' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.post("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412", null, {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_POST, true);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"POST\", \"https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .POST(HttpRequest.BodyPublishers.noBody())
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.PostAsync("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412", null);

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412"

            oHttp.Open "POST", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "404":
          description: Webhook o NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
    delete:
      summary: Desasociar NIF a webhook
      tags:
        - Webhooks
      parameters:
        - in: path
          name: webhook_id
          schema:
            type: string
          required: true
          description: Identificador del webhook
          example: 17067405-8c32-4efe-a7cb-8fad93403997
        - in: path
          name: nif
          schema:
            type: string
          required: true
          description: NIF
          example: B86561412
      description: Este endpoint permite desasociar un NIF concreto a un webhook concreto.
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |
            curl 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412' \
            --request DELETE \
            --header 'Authorization: Bearer <USER_API_KEY>'
        - lang: Python
          label: Python
          source: |
            import requests
            url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412'
            headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            }
            response = requests.delete(url, headers=headers)
        - lang: JavaScript
          label: JavaScript
          source: |
            const url = 'https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412';
            const headers = {
              'Authorization': 'Bearer <USER_API_KEY>'
            };
            fetch(url, { headers, method: 'DELETE' })
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error(error));
            }
        - lang: Node.js
          label: Node.js
          source: |-
            const axios = require("axios");

            const response = await axios.delete("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412", {
              headers: {
                "Authorization": "Bearer <API_KEY>"
              },
            });

            console.log(response.data);
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $url = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412";

            $headers = [
                "Authorization: Bearer <API_KEY>",
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            echo "HTTP Status: " . $httpCode . "\n";
            echo $response;
        - lang: Go
          label: Go
          source: "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc main() {\n\treq, err := http.NewRequest(\"DELETE\", \"https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(\"Authorization\", \"Bearer <API_KEY>\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tfmt.Println(\"Status:\", resp.StatusCode)\n\tfmt.Println(string(respBody))\n}"
        - lang: Java
          label: Java
          source: |-
            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;

            public class Main {
                public static void main(String[] args) throws Exception {
                    HttpClient client = HttpClient.newHttpClient();

                    HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412"))
                        .header("Authorization", "Bearer <API_KEY>")
                        .DELETE()
                        .build();

                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString());

                    System.out.println(response.statusCode());
                    System.out.println(response.body());
                }
            }
        - lang: C#
          label: C#
          source: |-
            using System;
            using System.Net.Http;
            using System.Text;
            using System.Threading.Tasks;

            class Program
            {
                static async Task Main()
                {
                    using var client = new HttpClient();
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer <API_KEY>");

                    var response = await client.DeleteAsync("https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412");

                    var responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Status: {response.StatusCode}");
                    Console.WriteLine(responseBody);
                }
            }
        - lang: VB6
          label: VB6
          source: |-
            Dim oHttp As Object
            Dim sUrl As String
            Dim sResponse As String

            Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")

            sUrl = "https://api.verifacti.com/webhooks/17067405-8c32-4efe-a7cb-8fad93403997/nifs/B86561412"

            oHttp.Open "DELETE", sUrl, False
            oHttp.setRequestHeader "Authorization", "Bearer <API_KEY>"

            oHttp.send

            sResponse = oHttp.responseText
            Debug.Print "Status: " & oHttp.Status
            Debug.Print sResponse

            Set oHttp = Nothing
      responses:
        "200":
          $ref: "#/components/responses/okResponse"
        "204":
          description: NIF desasociado del webhook correctamente (sin contenido)
        "404":
          description: Webhook o NIF no encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        "401":
          $ref: "#/components/responses/unauthorizedResponse"
        "500":
          $ref: "#/components/responses/serverErrorResponse"
components:
  schemas:
    WebhookNotification:
      type: array
      description: |
        Cuerpo enviado a la URL del webhook. Es un array con un elemento por cada registro de facturación
        incluido en el envío que generó la notificación.
      items:
        $ref: "#/components/schemas/WebhookNotificationItem"
      example:
        - uuid: b018ced3-b362-4494-8776-9eefff1c160c
          nif: A15022510
          serie: A
          numero: "34547"
          fecha_expedicion: 13-02-2026
          operacion: Alta
          url: https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=A15022510&numserie=A34547&fecha=13-02-2026&importe=242
          estado: Correcto
        - uuid: f4504c29-78ca-4491-9a10-b6b727a20c36
          nif: A15022510
          serie: A
          numero: "34548"
          fecha_expedicion: 13-02-2026
          operacion: Alta
          url: https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=A15022510&numserie=A34548&fecha=13-02-2026&importe=751
          estado: Aceptado con errores
          codigo_error: "2005"
          mensaje_error: El campo ImporteTotal tiene un valor incorrecto para el valor de los campos BaseImponibleOimporteNoSujeto, CuotaRepercutida y CuotaRecargoEquivalencia suministrados.
    WebhookNotificationItem:
      type: object
      description: |
        Resultado de un registro de facturación. La forma es idéntica a la que devolvería el endpoint
        `Estado registro` de las APIs de Verifactu o TicketBai.
      properties:
        uuid:
          type: string
          format: uuid
          description: Identificador del registro de facturación en nuestra plataforma.
          example: b018ced3-b362-4494-8776-9eefff1c160c
        nif:
          type: string
          description: NIF del emisor al que pertenece el registro.
          example: A15022510
        serie:
          type: string
          description: Serie de la factura.
          example: A
        numero:
          type: string
          description: Número de la factura.
          example: "34547"
        fecha_expedicion:
          type: string
          description: Fecha de expedición de la factura en formato `DD-MM-YYYY`.
          example: 13-02-2026
        operacion:
          type: string
          description: |
            Tipo de operación realizada sobre el registro. En las notificaciones de Verifactu los valores posibles son:
            <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
              <li>Alta</li>
              <li>Subsanacion</li>
              <li>Anulación</li>
              <li>Alta (rechazo previo)</li>
              <li>Alta (rechazo previo de subsanacion)</li>
              <li>Anulación (rechazo previo)</li>
              <li>Anulación (sin registro)</li>
              <li>Anulación (rechazo previo sin registro)</li>
            </ul>

            En las notificaciones de TicketBai los valores posibles son:
            <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
              <li>Alta</li>
              <li>Subsanacion</li>
              <li>Modificacion</li>
              <li>Anulación</li>
              <li>Anulación (rechazo previo)</li>
            </ul>
          example: Alta
        estado:
          type: string
          description: |
            Estado del registro de facturación. Los valores posibles coinciden con los del endpoint `Estado registro`:
            <ul style="list-style: disc; margin-top: 6px; margin-bottom: 0px;">
              <li>Pendiente: Registro encolado y no procesado aún.</li>
              <li>Correcto: Registro procesado correctamente por hacienda.</li>
              <li>Aceptado con errores: Aceptado con errores; se requiere subsanación o rectificativa.</li>
              <li>Incorrecto: Rechazado por hacienda; se requiere subsanación o rectificativa.</li>
              <li>Duplicado: No aceptado por existir un registro con la misma (serie, numero, fecha_expedicion).</li>
              <li>Anulado: Registro de anulación procesado correctamente.</li>
              <li>Factura inexistente: Anulación no aceptada por no existir la factura.</li>
              <li>No registrado: Rechazado por hacienda.</li>
              <li>Error servidor AEAT: Error transitorio en hacienda; se reintentará automáticamente.</li>
            </ul>
          example: Correcto
        url:
          type: string
          description: URL de verificación del código QR.
          example: https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=A15022510&numserie=A34547&fecha=13-02-2026&importe=242
        codigo_error:
          type: string
          description: |
            Código de error tal y como aparece en el sistema de hacienda. Solo presente en notificaciones de Verifactu y
            cuando `estado` indica error (`Aceptado con errores`, `Incorrecto`, `No registrado`, etc.).
          example: "2005"
        mensaje_error:
          type: string
          description: |
            Descripción del error tal y como aparece en el sistema de hacienda. Presente cuando `estado` indica error.
          example: El campo ImporteTotal tiene un valor incorrecto para el valor de los campos suministrados.
        estado_registro_duplicado:
          type: string
          description: |
            Estado del registro previamente existente. Solo presente en notificaciones de Verifactu cuando
            `estado` es `Duplicado`.
        tbai:
          type: string
          description: |
            Huella (hash) del registro TicketBai. Solo presente en notificaciones de TicketBai.
  responses:
    unauthorizedResponse:
      description: No autorizado — API key inválida o ausente.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
    serverErrorResponse:
      description: Error interno del servidor.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
    okResponse:
      description: OK
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                description: Mensaje.
                type: string
                example: OK
    nifResponse:
      description: NIF
      content:
        application/json:
          schema:
            type: object
            properties:
              nif:
                description: NIF.
                type: string
                example: B86561412
              entorno:
                description: Entorno del NIF.
                type: string
                example: test
              hacienda:
                description: |
                  Hacienda a la que está vinculado el NIF. Los valores posibles son:
                  <ol style="list-style-type: disc">
                    <li>verifactu</li>
                    <li>alava</li>
                    <li>guipuzcoa</li>
                    <li>vizcaya</li>
                  </ol>
                type: string
                example: verifactu
              webhooks:
                description: Lista de identificadores de los webhooks a los que esta asociado el NIF.
                type: array
                items:
                  type: string
                  example: 17067405-8c32-4efe-a7cb-8fad93403997
              nombre:
                description: Nombre y apellidos o razón social del NIF.
                type: string
                example: Mi empresa SL
              activo:
                description: Indica si el NIF está activo o no.
                type: boolean
                example: true
              direccion:
                description: Dirección del NIF.
                type: string
                example: Calle Mayor 15
              cp:
                description: Código postal del NIF.
                type: string
                example: "28040"
              poblacion:
                description: Población del NIF.
                type: string
                example: Madrid
              provincia:
                description: Provincia del NIF.
                type: string
                example: Madrid
              fecha_creacion:
                description: Fecha de creación del NIF.
                type: string
                example: 2024-12-01T12:18:21.671Z
              fecha_modificacion:
                description: Fecha de la última modificación del NIF.
                type: string
                example: 2024-12-07T16:16:51.671Z
              pagado_hasta:
                type: string
                example: 2025-06-04T00:00:00.000Z
                description: |
                  Campo solo disponible para NIFs de producción, ya que son los únicos por los que hay que pagar.
                  Este campo indica la fecha hasta la que se ha pagado el NIF. En caso de que llegada esa fecha el NIF esté activo,
                  entonces se renovará automáticamente y dicha fecha se actualizará automáticamente.
              representacion:
                enum:
                  - Correcto
                  - Rechazado
                  - Inexistente
                example: Correcto
                description: |
                  Indica el estado del modelo de representación del NIF. Los valores posibles son:
                  <ul style="list-style-type: disc">
                    <li>Correcto: El modelo de representación se ha recibido y se ha validado correctamente.</li>
                    <li>Rechazado: El modelo de representación ha sido recibido pero no se ha podido validar.</li>
                    <li>Inexistente: No se ha recibido el modelo de representación firmado.</li>
                  </ul>

                  Únicamente está presente este campo para los NIFs de Verifactu. Para NIFs de producción se requiere que el estado de la
                  representación sea "Correcto" para poder enviar facturas.
                type: string
              pdf:
                type: string
                example: https://bucket.com/4f4a6b5b-8c32-4efe-a7cb-8fad93403997.pdf
                description: |
                  URL donde está alojado el modelo de representación para este NIF en caso de que haya sido enviada. Esta URL tiene una validez
                  de 15 minutos desde el momento de realizar la petición. Únicamente está presente este campo para los NIFs de Verifactu.
              label:
                type: string
                example: Cliente A
                description: Etiqueta asociada al NIF. Puede ser `null` si no se ha asignado ninguna.
    webhookResponse:
      description: Webhook
      content:
        application/json:
          schema:
            type: object
            properties:
              id:
                description: Identificador del webhook.
                type: string
              url:
                description: URL a la que se hará la llamada cuando se dispare el webhook.
                type: string
              entorno:
                description: Entorno del webhook. Puede ser "test" o "prod".
                type: string
              secret:
                description: Clave para generar la firma HMAC.
                type: string
              activo:
                description: Indica si el webhook está activo o no.
                type: boolean
              nifs:
                type: array
                description: |
                  Lista de NIFs. Cuando se envían registros de facturación para cualquiera de estos NIFs, se dispara el webhook con el resultado
                  de hacienda una vez obtenido.
                items:
                  type: string
            example:
              id: 17067405-8c32-4efe-a7cb-8fad93403997
              url: https://api.webdelcliente.com/webhook
              entorno: test
              secret: mi-secreto
              activo: true
              nifs:
                - B86561412
                - B01345232
