openapi: 3.1.0
info:
  title: vatcheckapi
  version: "2"
  summary: VAT number validation and EU VAT registration lookup.
  description: >-
    vatcheckapi validates VAT numbers (format and checksum) and looks up their
    registration details, with single and batch validation. All endpoints are
    served over HTTPS and return JSON. Authenticate every request with your API
    key, either as the `apikey` query parameter or the `apikey` request header.


    This document is generated from the vatcheckapi service implementation and is
    the machine-readable source of truth for the v2 REST API. A human-readable
    version is available at https://vatcheckapi.com/docs.
  contact:
    name: vatcheckapi support
    email: support@vatcheckapi.com
    url: https://support.vatcheckapi.com/
servers:
  - url: https://api.vatcheckapi.com
    description: Production
security:
  - ApiKeyQuery: []
  - ApiKeyHeader: []
tags:
  - name: Validation
    description: Single VAT number validation.
  - name: Batches
    description: Bulk VAT number validation.
  - name: Metadata
    description: Account status.
paths:
  /v2/check:
    get:
      tags: [Validation]
      summary: Check a VAT number
      operationId: check
      description: >-
        Validates a VAT number's format and checksum and returns its
        registration information. The country code may be supplied separately or
        prefixed on the VAT number (e.g. `LU26375245`).
      parameters:
        - name: vat_number
          in: query
          required: true
          description: >-
            The VAT number to check, with or without the two-letter country
            prefix.
          schema: { type: string }
          example: "LU26375245"
        - name: country_code
          in: query
          required: false
          description: >-
            Two-letter country code. Required if the VAT number is not prefixed
            with it.
          schema: { type: string }
          example: "LU"
      responses:
        '200':
          description: VAT validation result.
          headers:
            X-RateLimit-Remaining-Quota-Month: { $ref: '#/components/headers/RateLimitRemainingQuotaMonth' }
            X-Cost: { $ref: '#/components/headers/Cost' }
          content:
            application/json:
              schema: { $ref: '#/components/schemas/VatCheckResult' }
              example:
                country_code: "LU"
                vat_number: "26375245"
                format_valid: true
                checksum_valid: true
                registration_info:
                  is_registered: true
                  name: "AMAZON EUROPE CORE S.A R.L."
                  address: "38, AVENUE JOHN F. KENNEDY\nL-1855  LUXEMBOURG"
                  address_parts: null
                  checked_at: "2023-01-11T12:30:28.000000Z"
                registration_info_history: []
        '401': { $ref: '#/components/responses/Unauthorized' }
        '422':
          description: The VAT number is invalid or the country is not supported.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Error' }
              example: { message: "Invalid VAT number." }
        '429': { $ref: '#/components/responses/RateLimited' }
  /v2/batches:
    get:
      tags: [Batches]
      summary: List batches
      operationId: listBatches
      description: Returns the VAT validation batches for your account.
      responses:
        '200':
          description: A list of batches.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/Batch' }
                required: [data]
        '401': { $ref: '#/components/responses/Unauthorized' }
    post:
      tags: [Batches]
      summary: Create a batch
      operationId: createBatch
      description: >-
        Creates a batch job that validates many VAT numbers asynchronously
        (up to 1000).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: [string, "null"]
                  maxLength: 255
                  description: Optional name for the batch. Auto-generated when omitted.
                vat_ids:
                  type: array
                  maxItems: 1000
                  items: { type: string }
                  description: The VAT numbers to validate.
              required: [vat_ids]
            example:
              name: "January suppliers"
              vat_ids: ["LU26375245", "DE811907980"]
      responses:
        '200':
          description: The created batch.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { $ref: '#/components/schemas/Batch' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '422': { $ref: '#/components/responses/ValidationError' }
  /v2/batches/{batchId}:
    get:
      tags: [Batches]
      summary: Get a batch
      operationId: getBatch
      description: Returns a single batch and its progress.
      parameters:
        - { $ref: '#/components/parameters/BatchId' }
      responses:
        '200':
          description: The batch.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { $ref: '#/components/schemas/Batch' }
              example:
                data:
                  id: 42
                  status: "IN_PROGRESS"
                  name: "January suppliers"
                  total_validations: 2
                  pending_validations: 1
                  successful_validations: 1
                  created_at: "2023-01-11T12:30:28Z"
                  started_at: "2023-01-11T12:30:29Z"
                  finished_at: null
        '401': { $ref: '#/components/responses/Unauthorized' }
        '404': { $ref: '#/components/responses/NotFound' }
  /v2/batches/{batchId}/validations:
    get:
      tags: [Batches]
      summary: List batch validations
      operationId: getBatchValidations
      description: Returns the individual VAT validation results within a batch.
      parameters:
        - { $ref: '#/components/parameters/BatchId' }
      responses:
        '200':
          description: The validations in the batch.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/BatchValidation' }
                required: [data]
              example:
                data:
                  - id: 101
                    status: "DONE"
                    vat_id: "LU26375245"
                    response:
                      country_code: "LU"
                      vat_number: "26375245"
                      format_valid: true
                    created_at: "2023-01-11T12:30:28Z"
                    updated_at: "2023-01-11T12:30:31Z"
        '401': { $ref: '#/components/responses/Unauthorized' }
        '404': { $ref: '#/components/responses/NotFound' }
  /v2/status:
    get:
      tags: [Metadata]
      summary: Account quota status
      operationId: getStatus
      description: Returns your quota usage. Does not count against your quota.
      responses:
        '200':
          description: Current quota usage.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/StatusResponse' }
              example:
                account_id: 313373133731337
                quotas:
                  month: { total: 300, used: 72, remaining: 228 }
                  grace: { total: 0, used: 0, remaining: 0 }
        '401': { $ref: '#/components/responses/Unauthorized' }
components:
  securitySchemes:
    ApiKeyQuery: { type: apiKey, in: query, name: apikey, description: "API key as the apikey query parameter." }
    ApiKeyHeader: { type: apiKey, in: header, name: apikey, description: "API key as the apikey request header (recommended)." }
  parameters:
    BatchId:
      name: batchId
      in: path
      required: true
      description: The batch id.
      schema: { type: integer }
      example: 42
  headers:
    RateLimitRemainingQuotaMonth:
      description: Remaining requests in your monthly quota.
      schema: { type: integer }
      example: 228
    Cost:
      description: Requests this call counted against your quota.
      schema: { type: integer }
      example: 1
  responses:
    Unauthorized:
      description: An API key was supplied but is invalid.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
          example: { message: "If you specify an apikey it has to be a valid one." }
    NotFound:
      description: The batch was not found.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
          example: { message: "Batch not found" }
    ValidationError:
      description: One or more request parameters failed validation.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ValidationError' }
          example:
            message: "Validation error"
            errors: { vat_ids: ["The vat_ids may not have more than 1000 items."] }
    RateLimited:
      description: You have exceeded your monthly quota or minute rate limit.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
          example: { message: "You have reached your monthly limit, please upgrade your plan" }
  schemas:
    VatCheckResult:
      type: object
      properties:
        country_code: { type: string, example: "LU" }
        vat_number: { type: string, example: "26375245" }
        format_valid: { type: boolean }
        checksum_valid: { type: boolean }
        registration_info:
          type: object
          properties:
            is_registered: { type: boolean }
            name: { type: [string, "null"], example: "AMAZON EUROPE CORE S.A R.L." }
            address: { type: [string, "null"] }
            address_parts: { type: [object, "null"], additionalProperties: true }
            checked_at: { type: [string, "null"], example: "2023-01-11T12:30:28.000000Z" }
        registration_info_history:
          type: array
          items: { type: object, additionalProperties: true }
      required: [country_code, vat_number, format_valid, checksum_valid]
    Batch:
      type: object
      properties:
        id: { type: integer, example: 42 }
        status: { type: string, example: "IN_PROGRESS" }
        name: { type: [string, "null"], example: "January suppliers" }
        total_validations: { type: integer, example: 2 }
        pending_validations: { type: integer, example: 1 }
        successful_validations: { type: integer, example: 1 }
        created_at: { type: [string, "null"], example: "2023-01-11T12:30:28Z" }
        started_at: { type: [string, "null"] }
        finished_at: { type: [string, "null"] }
    BatchValidation:
      type: object
      properties:
        id: { type: integer, example: 101 }
        status: { type: string, example: "DONE" }
        vat_id: { type: string, example: "LU26375245" }
        response: { type: [object, "null"], additionalProperties: true }
        created_at: { type: [string, "null"] }
        updated_at: { type: [string, "null"] }
    StatusResponse:
      type: object
      properties:
        account_id: { type: integer, example: 313373133731337 }
        quotas:
          type: object
          properties:
            month: { $ref: '#/components/schemas/QuotaBucket' }
            grace: { $ref: '#/components/schemas/QuotaBucket' }
          required: [month]
      required: [quotas]
    QuotaBucket:
      type: object
      properties:
        total: { type: integer, example: 300 }
        used: { type: integer, example: 72 }
        remaining: { type: integer, example: 228 }
    Error:
      type: object
      properties: { message: { type: string }, info: { type: string } }
      required: [message]
    ValidationError:
      type: object
      properties:
        message: { type: string, example: "Validation error" }
        errors:
          type: object
          additionalProperties: { type: array, items: { type: string } }
        info: { type: string }
      required: [message, errors]
