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

# Validate employee import rows from JSON (no persistence)



## OpenAPI

````yaml /openapi/fluide-hr.json post /api/v1/hr/employees/bulk/validate-rows
openapi: 3.0.0
info:
  title: Fluide HR API
  description: >-
    Employee records, contracts, leave, performance, OKRs, and HR insights. HR
    is the canonical employee source consumed by payroll and other suite
    services. In the API playground, click Authorize and provide Bearer JWT,
    X-Fluide-Api-Key, and X-Fluide-Client-Id (fluide-developer).
  version: '1.0'
  contact: {}
servers:
  - url: https://sandbox.fluidehr.com
    description: Sandbox
security:
  - bearer: []
    fluideApiKey: []
    fluideClientId: []
tags:
  - name: Health
    description: >-
      Liveness and readiness probes. Returns dependency status (database, Redis,
      etc.) for orchestrators and uptime monitors.
    x-group: Operations
  - name: Prometheus
    description: >-
      Prometheus scrape endpoint in text exposition format. Configure your
      metrics collector to poll this path on each service.
    x-group: Operations
  - name: Audit
  - name: HR Employees
    description: Create and manage employee records tied to your organization.
  - name: Onboarding
  - name: HR Employment contracts
  - name: Leave
  - name: Leave accrual
  - name: Performance
  - name: OKR
  - name: Country configuration (CCS)
  - name: Compliance
  - name: Insights
  - name: Dashboard
  - name: Attendance
  - name: Geofence sites
  - name: Recruitment
  - name: Workforce planning
  - name: Expenses
  - name: Benefits
  - name: Loans
  - name: Timesheets
  - name: Talent
paths:
  /api/v1/hr/employees/bulk/validate-rows:
    post:
      tags:
        - HR Employees
      summary: Validate employee import rows from JSON (no persistence)
      operationId: EmployeesController_validateBulkRows
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkValidateJsonDto'
      responses:
        '201':
          description: Validate employee import rows from JSON (no persistence) — created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiResponseDto'
                  - properties:
                      data:
                        description: Endpoint-specific payload
        '400':
          description: Validation failed or invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '401':
          description: Missing or invalid JWT / API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '403':
          description: Token valid but insufficient permission for this operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
        '404':
          description: Resource not found or outside caller scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponseDto'
      security:
        - bearer: []
          fluideApiKey: []
          fluideClientId: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            curl -sS -X POST
            "$FLUIDE_BASE_URL/api/v1/hr/employees/bulk/validate-rows" \
              -H "Authorization: Bearer $FLUIDE_ACCESS_TOKEN" \
              -H "X-Fluide-Api-Key: $FLUIDE_API_KEY" \
              -H "X-Fluide-Client-Id: fluide-developer" \
              -H "Content-Type: application/json" \
              -d '{}'
        - lang: node
          label: Node.js
          source: >-
            const baseUrl = process.env.FLUIDE_BASE_URL;


            const response = await
            fetch(`${baseUrl}/api/v1/hr/employees/bulk/validate-rows`, {
              method: 'POST',
              headers: {
                Authorization: `Bearer ${process.env.FLUIDE_ACCESS_TOKEN}`,
                'X-Fluide-Api-Key': process.env.FLUIDE_API_KEY,
                'X-Fluide-Client-Id': 'fluide-developer',
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({}),
            });


            if (!response.ok) throw new Error(`HTTP ${response.status}: ${await
            response.text()}`);

            console.log(await response.json());
        - lang: python
          label: Python
          source: |-
            import os
            import requests

            base_url = os.environ["FLUIDE_BASE_URL"]
            headers = {
                    "Authorization": f"Bearer {os.environ['FLUIDE_ACCESS_TOKEN']}",
                    "X-Fluide-Api-Key": os.environ["FLUIDE_API_KEY"],
                    "X-Fluide-Client-Id": "fluide-developer",
            }

            response = requests.post(
                f"{base_url}/api/v1/hr/employees/bulk/validate-rows",
                headers=headers,
                json={},
                timeout=30,
            )
            response.raise_for_status()
            print(response.json())
        - lang: java
          label: Java
          source: >-
            import java.net.URI;

            import java.net.http.HttpClient;

            import java.net.http.HttpRequest;

            import java.net.http.HttpResponse;


            String baseUrl = System.getenv("FLUIDE_BASE_URL");

            HttpClient client = HttpClient.newHttpClient();

            HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/api/v1/hr/employees/bulk/validate-rows"))
                .header("Authorization", "Bearer " + System.getenv("FLUIDE_ACCESS_TOKEN"))
                .header("X-Fluide-Api-Key", System.getenv("FLUIDE_API_KEY"))
                .header("X-Fluide-Client-Id", "fluide-developer")
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString("{}"))
                .build();
            HttpResponse<String> response = client.send(builder.build(),
            HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() >= 400) throw new RuntimeException("HTTP "
            + response.statusCode() + ": " + response.body());

            System.out.println(response.body());
        - lang: php
          label: PHP
          source: >-
            <?php

            $baseUrl = getenv("FLUIDE_BASE_URL");

            $ch = curl_init($baseUrl .
            "/api/v1/hr/employees/bulk/validate-rows");

            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_CUSTOMREQUEST => 'POST',
                CURLOPT_HTTPHEADER => [
                    'Authorization: Bearer ' . getenv('FLUIDE_ACCESS_TOKEN'),
                    'X-Fluide-Api-Key: ' . getenv('FLUIDE_API_KEY'),
                    'X-Fluide-Client-Id: fluide-developer',
                    'Content-Type: application/json',
                ],
                CURLOPT_POSTFIELDS => "{}",
            ]);

            $response = curl_exec($ch);

            if ($response === false) throw new
            RuntimeException(curl_error($ch));

            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

            if ($status >= 400) throw new RuntimeException("HTTP $status:
            $response");

            echo $response;
components:
  schemas:
    BulkValidateJsonDto:
      type: object
      properties:
        rows:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/EmployeeBulkRowDto'
      required:
        - rows
    ApiResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
          description: Whether the request succeeded
        message:
          type: string
          example: Operation completed successfully
          description: Human-readable outcome message (localized when i18n is configured)
        data:
          type: object
          description: Response payload when success is true
      required:
        - success
        - message
    ApiErrorResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: Validation failed
          description: Human-readable error message (localized when i18n is configured)
        code:
          type: string
          example: VALIDATION_FAILED
          description: Stable machine-readable error code for client handling and support
        errors:
          type: object
          description: Field-level validation errors keyed by property name
          example:
            from:
              - from must be a valid date
        statusCode:
          type: number
          example: 400
        timestamp:
          type: string
          example: '2026-06-03T12:00:00.000Z'
      required:
        - success
        - message
        - code
        - statusCode
        - timestamp
    EmployeeBulkRowDto:
      type: object
      properties:
        firstName:
          type: string
          maxLength: 100
        lastName:
          type: string
          maxLength: 100
        email:
          type: string
          format: email
        phone:
          type: string
          maxLength: 32
        role:
          type: string
          description: >-
            Optional org role hint for SEND_INVITE (stored under
            profileExtensions.bulkImport).
          maxLength: 32
        departmentId:
          type: string
          maxLength: 100
        jobTitle:
          type: string
          maxLength: 100
          description: Job title → designation
        salary:
          type: number
        hireDate:
          type: string
        employmentType:
          type: string
          maxLength: 32
        employeeCode:
          type: string
          maxLength: 50
          description: Leave blank to auto-generate on commit
        currency:
          type: string
          maxLength: 3
      required:
        - firstName
        - lastName
        - email
        - hireDate
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Access token JWT. Use as Authorization: Bearer <token>. In the API
        playground, paste the JWT only.
    fluideApiKey:
      type: apiKey
      in: header
      name: X-Fluide-Api-Key
      description: >-
        Developer API key (fl_dev_...). Required on every API call with a
        machine access token.
      x-default: fl_dev_your_key
    fluideClientId:
      type: apiKey
      in: header
      name: X-Fluide-Client-Id
      description: >-
        First-party client audience. Must match the fluide_client_id claim on
        the JWT. Use fluide-developer for Connect.
      x-default: fluide-developer

````