> ## Documentation Index
> Fetch the complete documentation index at: https://www.finseed.es/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Validate a tax id

> Checks a Spanish NIF/CIF/NIE against the AEAT census (id and name together) or an EU VAT number against VIES, exactly as invoice creation does just-in-time. Use it in checkout or onboarding forms to catch bad recipient data before issuing. Validation failures are outcomes, not errors: the endpoint answers 200 with `valid: false`. Rate limited per API key.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/tax_ids/validate
openapi: 3.1.0
info:
  title: Finseed API
  version: 1.0.0
  description: >-
    REST API for programmatic Verifactu invoicing. Every request is sent over
    HTTPS and authenticated with an API key passed as a bearer token. Each key
    is scoped to a single environment (test or live). Payloads are JSON with
    snake_case fields: amounts are integer minor units (cents) and timestamps
    are RFC 3339 in UTC. List endpoints are cursor-paginated. Errors return a
    small application/json envelope with a stable, machine-readable `code`.
servers:
  - url: https://api.finseed.es
security:
  - bearerAuth: []
paths:
  /v1/tax_ids/validate:
    post:
      tags:
        - Tax IDs
      summary: Validate a tax id
      description: >-
        Checks a Spanish NIF/CIF/NIE against the AEAT census (id and name
        together) or an EU VAT number against VIES, exactly as invoice creation
        does just-in-time. Use it in checkout or onboarding forms to catch bad
        recipient data before issuing. Validation failures are outcomes, not
        errors: the endpoint answers 200 with `valid: false`. Rate limited per
        API key.
      operationId: validateTaxId
      requestBody:
        description: The tax id and registered name to validate.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaxIdValidateRequest'
      responses:
        '200':
          description: The validation outcome.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaxIdValidateResult'
        '400':
          description: >-
            The request was rejected during validation. The `errors` array lists
            each failing field with a reason, so you can map the failure back to
            a specific parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: invalid_request
                detail: >-
                  The request is not valid. A parameter is missing, malformed,
                  or out of range. See the `errors` array for the fields that
                  failed.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#invalid_request
        '401':
          description: >-
            Authentication failed: the API key is missing, malformed, or
            revoked. Send a valid key as a bearer token in the `Authorization`
            header. Each key is bound to a single environment (test or live).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: unauthorized
                detail: >-
                  Authentication failed. Send your API key as a bearer token in
                  the `Authorization` header. Keys are scoped to one
                  environment, so a test key cannot read live data and vice
                  versa.
                errors: []
                doc_url: https://www.finseed.es/docs/api-reference/errors#unauthorized
        '429':
          description: >-
            The per-key rate limit for this endpoint was exceeded. The response
            carries a `Retry-After` header with the seconds to wait. Spread out
            bursts or batch your work; sustained limits are documented per
            endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: rate_limited
                detail: >-
                  Too many requests for this endpoint with this API key. Wait
                  for the interval in the Retry-After header and try again.
                errors: []
                doc_url: https://www.finseed.es/docs/api-reference/errors#rate_limited
        '500':
          description: >-
            An unexpected error occurred on our side. No partial work is
            persisted, so the request can be retried safely.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                code: internal_error
                detail: >-
                  Something went wrong on our side. The request did not complete
                  and can be retried safely.
                errors: []
                doc_url: >-
                  https://www.finseed.es/docs/api-reference/errors#internal_error
components:
  schemas:
    TaxIdValidateRequest:
      type: object
      properties:
        tax_id:
          type: string
          minLength: 1
          maxLength: 64
          description: >-
            The tax identifier to validate: a Spanish NIF/CIF/NIE or an EU VAT
            number. Whitespace and separators are tolerated.
          example: B12345678
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            Name the id should be registered under. Spanish NIFs are checked
            against the AEAT census together with this name; VIES checks the
            number only.
          example: ACME, S.L.
        country:
          description: >-
            ISO 3166-1 alpha-2 hint for ambiguous formats. Usually omitted: the
            country is detected from the id itself.
          example: ES
          type: string
          minLength: 2
          maxLength: 2
      required:
        - tax_id
        - name
      additionalProperties: false
      description: The tax id to validate against the census.
    TaxIdValidateResult:
      type: object
      properties:
        valid:
          type: boolean
          description: >-
            Whether the id passed validation. Only trust it when `definitive` is
            also true.
          example: true
        definitive:
          type: boolean
          description: >-
            Whether the answer is final. False means the id could not be
            conclusively checked (unrecognized format, or the census service is
            temporarily unavailable) — treat it as "unknown", not as invalid.
          example: true
        normalized_tax_id:
          type: string
          description: >-
            The id after normalization (whitespace and separators removed,
            uppercased). Use this form when creating invoices.
          example: B12345678
        tax_id_type:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The kind the id was classified as, or null when the format was not
            recognized. This is an extensible enum: new values may be added in
            the future, so clients must tolerate values not listed here. Known
            values: es_nif, eu_vat.
          example: es_nif
        tax_id_country:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            ISO 3166-1 alpha-2 country the id belongs to, or null when
            unclassified.
          example: ES
        error_code:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Stable, machine-readable reason validation failed, or null on
            success. Branch on this instead of parsing prose. This is an
            extensible enum: new values may be added in the future, so clients
            must tolerate values not listed here. Known values:
            unrecognized_format, invalid_format,
            not_registered_or_name_mismatch, vies_invalid, census_unavailable.
          example: not_registered_or_name_mismatch
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Human-readable English reason when valid is false, for your logs and
            support tooling. Derived from error_code. Null on success.
          example: null
        end_user_message:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Reason safe to show the end user (a shopper at checkout), in Spanish
            today. Null on success. Its language may become request-controlled
            in future without this field being renamed.
          example: null
      required:
        - valid
        - definitive
        - normalized_tax_id
        - tax_id_type
        - tax_id_country
        - error_code
        - error_message
        - end_user_message
      additionalProperties: false
      description: >-
        Outcome of a census validation. Validation failures are outcomes, not
        errors: the endpoint answers 200 with `valid: false` rather than a 4xx.
    ErrorEnvelope:
      type: object
      properties:
        code:
          type: string
          description: >-
            Stable, machine-readable error code. The branch key. This is an
            extensible enum: new values may be added in the future, so clients
            must tolerate values not listed here. Known values: invalid_request,
            unauthorized, invoice_not_found, download_link_expired,
            number_series_not_found, number_series_prefix_taken,
            number_series_in_use, customer_not_found, customer_ambiguous,
            idempotency_conflict, rate_limited, invalid_number_series,
            invalid_tax_rate, invalid_tax_data, invalid_tax_id,
            tax_id_type_country_mismatch, insufficient_recipient_data,
            simplified_amount_exceeded, simplified_incompatible_tax_type,
            invalid_recargo_equivalencia, aeat_mandate_not_approved,
            no_active_subscription, tax_id_validation_unavailable,
            invalid_rectifies_reference, rectified_invoice_not_found,
            invoice_already_voided, invoice_already_replaced,
            invoice_not_family_tip, invoice_pending_at_aeat,
            invoice_not_rectifiable_at_aeat, family_balance_below_zero,
            replacement_total_negative, reason_incompatible_with_recipient,
            recipient_overrides_not_allowed_for_differences,
            rectifying_series_invalid, external_reference_invalid,
            external_reference_matches_existing_invoice,
            rectified_amounts_required_for_substitution,
            line_item_without_tax_items, internal_error.
          example: invalid_request
        detail:
          type: string
          description: Human-readable, context-specific explanation.
          example: The query parameters are not valid.
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                description: Location of the offending value (JSON path).
                example: limit
              code:
                type: string
                description: Machine-readable validation issue code.
                example: too_big
              message:
                type: string
                description: Human-readable explanation of the field-level issue.
                example: Number must be less than or equal to 100
            required:
              - field
              - code
              - message
            additionalProperties: false
          description: >-
            Field-level issues. Always present; empty unless this is a
            validation failure.
        doc_url:
          type: string
          description: Link to the reference documentation for this error code.
          example: https://www.finseed.es/docs/api-reference/errors#invalid_request
      required:
        - code
        - detail
        - errors
        - doc_url
      additionalProperties: false
      description: >-
        Uniform error body returned for every non-2xx response
        (application/json).
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key sent as a bearer token in the `Authorization` header.

````