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

# Bulk-create screens from a CSV file

> Parses an uploaded CSV of candidates and creates one `ss_screen`
post per valid row. Optionally sends invite emails immediately.

Max 100 candidates per upload. Each row is validated
independently — partial success is possible.

**CSV format:** `First Name,Last Name,Email,Phone[,Company][,URL]`
Headers are auto-detected; if absent, column order is assumed.

Requires login + council read access.




## OpenAPI

````yaml /openapi/private/specs/wp/wp-ajax-misc.yml post /wp-admin/admin-ajax.php?action=upload_candidates_csv
openapi: 3.1.0
info:
  title: SageScreen — Misc AJAX Modules (User · Council · Billing · Splash · Demo)
  version: 1.0.0
servers:
  - url: https://{domain}/wp-json/sagescreen/v1
    description: WordPress REST API
    variables:
      domain:
        default: api.sagescreen.app
security: []
tags:
  - name: User – REST
    description: Zapier-facing REST endpoints
  - name: User – AJAX
    description: Council user management AJAX endpoints
  - name: User – Profile
    description: Self-service profile updates
  - name: Council – REST
    description: Zapier-facing REST endpoints for council data sync
  - name: Council – AJAX
    description: Council user and sage management AJAX endpoints
  - name: Billing – Stripe
    description: Stripe webhook and subscription endpoints
  - name: Billing – Broadcast
    description: Postmark broadcast unsubscribe endpoint
  - name: Billing – Pipedrive
    description: Pipedrive CRM ID set-* webhook endpoints (called by Zapier)
  - name: Billing – AJAX
    description: Credit ledger, reactivation, and portal AJAX endpoints
  - name: Splash
    description: Splash banner AJAX endpoints
  - name: Demo
    description: Demo signup and management AJAX endpoints
  - name: CSV Upload
    description: Bulk candidate CSV upload
paths:
  /wp-admin/admin-ajax.php?action=upload_candidates_csv:
    post:
      tags:
        - CSV Upload
      summary: Bulk-create screens from a CSV file
      description: |
        Parses an uploaded CSV of candidates and creates one `ss_screen`
        post per valid row. Optionally sends invite emails immediately.

        Max 100 candidates per upload. Each row is validated
        independently — partial success is possible.

        **CSV format:** `First Name,Last Name,Email,Phone[,Company][,URL]`
        Headers are auto-detected; if absent, column order is assumed.

        Requires login + council read access.
      operationId: ajaxUploadCandidatesCsv
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UploadCsvRequest'
      responses:
        '200':
          description: Upload result (may include per-row errors)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/UploadCsvSuccess'
                  - $ref: '#/components/schemas/DemoInternalAjaxErrorResponse'
              examples:
                partialSuccess:
                  summary: 3 created, 1 error
                  value:
                    success: true
                    message: Processed 3 screens successfully, 1 errors
                    results:
                      - row_number: 1
                        firstName: John
                        lastName: Doe
                        email: john@example.com
                        status: success
                        message: Screen created successfully
                      - row_number: 2
                        firstName: Jane
                        lastName: Smith
                        email: jane@example.com
                        status: error
                        message: 'Duplicate: Screen already exists for this email'
                    created_count: 3
                    error_count: 1
                    total_count: 4
                noFile:
                  summary: No CSV uploaded
                  value:
                    success: false
                    message: No file uploaded
                wrongType:
                  summary: Not a CSV
                  value:
                    success: false
                    message: Only CSV files are allowed
      security:
        - wpAjaxNonce: []
components:
  schemas:
    UploadCsvRequest:
      type: object
      required:
        - action
        - nonce
        - council_sage_id
        - csvUploader
      properties:
        action:
          type: string
          const: upload_candidates_csv
        nonce:
          type: string
          description: WP nonce for `sagescreen_frontend_nonce`
        council_sage_id:
          type: integer
          description: Post ID of `ss_council_sage`
          examples:
            - 101
        csvUploader:
          type: string
          format: binary
          description: CSV file (`.csv` extension required)
        expiration_date:
          type: string
          description: Invite expiration date
          examples:
            - '2026-03-19'
        send_invite_now:
          type: string
          enum:
            - '0'
            - '1'
          description: '''1'' to send invite emails immediately'
          examples:
            - '1'
        email_from:
          type: string
          description: Sender display name
          examples:
            - Recruiting Team
        email_from_address:
          type: string
          format: email
          examples:
            - recruiting@example.com
        email_reply_to:
          type: string
          format: email
          examples:
            - hr@example.com
        email_subject:
          type: string
          examples:
            - You're Invited to Interview
        email_header:
          type: string
          examples:
            - Welcome!
        email_body:
          type: string
          description: HTML email body template
          examples:
            - <p>Hello ::FIRST_NAME::, click the link below.</p>
    UploadCsvSuccess:
      type: object
      properties:
        success:
          type: boolean
          const: true
        message:
          type: string
          examples:
            - Processed 3 screens successfully, 1 errors
        results:
          type: array
          items:
            $ref: '#/components/schemas/CsvRowResult'
        created_count:
          type: integer
          examples:
            - 3
        error_count:
          type: integer
          examples:
            - 1
        total_count:
          type: integer
          examples:
            - 4
    DemoInternalAjaxErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          const: false
        message:
          type: string
          examples:
            - Invalid security token
    CsvRowResult:
      type: object
      properties:
        row_number:
          type: integer
          examples:
            - 1
        firstName:
          type: string
          examples:
            - John
        lastName:
          type: string
          examples:
            - Doe
        email:
          type: string
          format: email
          examples:
            - john@example.com
        status:
          type: string
          enum:
            - success
            - error
          examples:
            - success
        message:
          type: string
          examples:
            - Screen created successfully
  securitySchemes:
    wpAjaxNonce:
      type: apiKey
      in: query
      name: nonce
      description: WordPress AJAX nonce (passed as form field, verified per-action)

````