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

# Import a CSV

> Import a CSV: one verification per row, created in the background. Poll the job for progress.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/link-templates/{slug}/import
openapi: 3.1.0
info:
  title: rial API
  version: 0.1.0
  description: 'Prove a photo is real. Base URL: https://api.rial.io'
  contact:
    name: rial-platform team
    url: https://github.com/Rial-ventures-Inc/rial-platform
  license:
    name: UNLICENSED — proprietary, internal use only
servers:
  - url: https://api.rial.io
    description: Production
security: []
tags:
  - name: Verifications
    description: >-
      Create, fetch, list, and finalize verifications. The core of the API —
      every tenant integration starts here.
  - name: Templates
    description: >-
      Publish, update, revoke and inspect link templates — the reusable capture
      links behind `/l/{token}` (a compact JWT carrying the org and template
      slugs; the legacy `/l/{org}/{slug}` keeps resolving). Callable with a
      secret key; each publish snapshots a versioned capture spec (GET-83).
  - name: Databases
    description: >-
      Create, update, inspect and synchronize tenant-scoped databases used by
      reusable verification templates. Callable with a dashboard session or
      secret API key.
paths:
  /v1/link-templates/{slug}/import:
    post:
      tags:
        - Templates
      summary: Import a CSV
      description: >-
        Import a CSV: one verification per row, created in the background. Poll
        the job for progress.
      parameters:
        - schema:
            type: string
            pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
            description: Template slug — lowercase `[a-z0-9-]`.
            example: warehouse-intake
          required: true
          name: slug
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CsvImportRequest'
            example:
              csv: |
                external_ref
                ci-inso-row-1
                ci-inso-row-2
      responses:
        '200':
          description: >-
            Identical bytes already submitted — the EXISTING job is returned
            with `duplicate: true`; nothing re-runs.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/LinkTemplateImportJob'
                  - type: object
                    properties:
                      duplicate:
                        type: boolean
                        enum:
                          - true
                    required:
                      - duplicate
        '202':
          description: Import job accepted — the worker mints verifications asynchronously.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  status:
                    type: string
                    enum:
                      - processing
                  total_rows:
                    type: integer
                  valid_rows:
                    type: integer
                  invalid_rows:
                    type: array
                    items:
                      type: object
                      properties:
                        row:
                          type: integer
                        reason:
                          type: string
                      required:
                        - row
                        - reason
                      description: >-
                        1-based CSV row (header is row 1) and why it was
                        rejected.
                  invalid_rows_total:
                    type: integer
                required:
                  - id
                  - status
                  - total_rows
                  - valid_rows
                  - invalid_rows
                  - invalid_rows_total
              example:
                id: imp_01HXYZABCDEFGHJKMNPQRSTVWX
                status: processing
                total_rows: 2
                valid_rows: 2
                invalid_rows: []
                invalid_rows_total: 0
        '400':
          description: Body failed validation (missing `csv`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No template with that slug for the authenticated tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: not_found
                  message: Resource not found
        '422':
          description: >-
            CSV rejected: unparseable, `no_valid_rows`, `too_many_invalid_rows`
            (>20%), or `quoted_headers_unsupported_with_mapping`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
        '503':
          description: The template store is unreachable — retry with backoff.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  cause:
                    type: string
                required:
                  - error
              example:
                error: storage_unavailable
      security:
        - bearerApiKey: []
components:
  schemas:
    CsvImportRequest:
      type: object
      properties:
        csv:
          type: string
          minLength: 1
          description: Raw CSV text, header row first.
        column_mapping:
          type: object
          additionalProperties:
            type: string
          description: Optional explicit header→field mapping when automap falls short.
      required:
        - csv
    LinkTemplateImportJob:
      type: object
      properties:
        id:
          type: string
        template_slug:
          type: string
        status:
          type: string
          enum:
            - processing
            - completed
            - failed
            - aborted
        total_rows:
          type: integer
        imported_rows:
          type: integer
        invalid_rows:
          type: array
          items:
            type: object
            properties:
              row:
                type: integer
              reason:
                type: string
            required:
              - row
              - reason
            description: 1-based CSV row (header is row 1) and why it was rejected.
        requested_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        failure_reason:
          type: string
      required:
        - id
        - template_slug
        - status
        - total_rows
        - imported_rows
        - invalid_rows
        - requested_at
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            fields:
              type: array
              items:
                type: object
                properties:
                  path:
                    type: string
                  message:
                    type: string
                required:
                  - path
                  - message
          required:
            - code
            - message
      required:
        - error
      description: >-
        Uniform error envelope. `code` is the stable string SDKs branch on
        (`invalid_request`, `unauthorized`, `not_found`, `expired`, `step_full`,
        `unknown_step`, `steps_incomplete`, `already_finalized`,
        `too_many_requests`, `storage_unavailable`, `internal_error`). `fields`
        is only present on `invalid_request` validation failures.
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: rk_secret_<key>
      description: >-
        Secret API key, created in the dashboard under Settings → API. Send it
        as `Authorization: Bearer rk_secret_…` from your server only.
        Publishable keys (`pk_live_…`) are for the native SDKs and reach the
        capture endpoints alone. An unknown key returns 401.

````