Hirevoice Docs

WhatsApp & Blue-collar (Preview)

Upcoming WhatsApp interview flow for blue-collar positions, with multi-language support and document gathering

Preview — this flow is in active development and is not yet available for integration partners. Field names and schemas described below may still change before release. Webhook events and lifecycle states reuse the structures documented in Integration V1.

Overview

For blue-collar positions, the standard browser-based voice interview is replaced by a WhatsApp conversation followed by a phone call. The Hirevoice agent uses WhatsApp to coordinate with the candidate — confirming they can be called, notifying them ahead of the call, and walking them through document gathering before and after the interview. Candidates do not need to install an app, open a link, or upload a CV.

To opt a position into this flow, set interview_type to "blue-collar" when creating it via POST /api/integration/v1/positions:

{
  "name": "Warehouse Operator",
  "job_description": "...",
  "company_position_uuid": "ext-pos-bc-001",
  "language": "es",
  "interview_type": "blue-collar"
}

Notes:

  • interview_type defaults to "white-collar" (the existing voice flow). Setting it to "blue-collar" switches the position to the WhatsApp flow.
  • cv_url is not required when creating candidates against a blue-collar position.
  • The position-level language is still used as the agent's default, but the candidate may switch language at the start of the WhatsApp conversation (see below).

How the WhatsApp agent behaves

The WhatsApp agent is not customizable in this preview. It runs a fixed conversation script tuned for blue-collar intake. To enable it, the only thing you need to do is set interview_type: "blue-collar" on the position.

What the agent does, in order:

  1. Greets the candidate and asks them to choose their preferred language. This selection overrides the position-level language for this candidate's interview.
  2. Runs the interview in the selected language, using the position's evaluation_criteria and extract_data configuration in the same way as the white-collar flow.
  3. Gathers documents requested by the position's document_gathering configuration (see next section). The agent prompts the candidate for each document, accepts media or PDF attachments through WhatsApp, and validates that the file type matches what was requested.
  4. Closes the conversation and emits the standard interview.completed webhook once the interview and all required documents are collected.

Multi-language support:

  • The agent currently handles es, ca, en, fr, and ur (Urdu) end-to-end, including the language picker, interview prompts, and document requests.
  • The agent's first message (the greeting and language picker) is sent in the position's configured language. From the candidate's reply onward, the candidate can choose to continue in their preferred language and every subsequent agent message — interview questions, document prompts, validation errors, closing — is localized to that selection.
  • The candidate's selected language is reported back on the interview payload via the existing applied_extract_data.language field.

Document gathering

Document gathering is an upcoming addition to the position contract that lets you declare which documents the WhatsApp agent should collect from the candidate after the interview. It is conceptually similar to extract_data (declarative key + description), but each item describes a file the candidate must provide rather than a piece of data to extract from the conversation.

Schema

document_gathering is an optional array of document type IDs. Each ID picks a predefined document type with built-in agent prompt, accepted file types, and extraction set — you cannot customize prompts, file types, or the extracted fields through the API yet.

{
  "name": "Warehouse Operator",
  "company_position_uuid": "ext-pos-bc-001",
  "language": "es",
  "interview_type": "blue-collar",
  "document_gathering": ["national_id", "forklift_license", "work_permit"]
}

The catalog of supported document type IDs is not published yet — Hirevoice will share the available IDs with you directly during onboarding. Treat them as opaque strings; do not hardcode assumptions about the set.

Rules:

  • document_gathering is only honored when interview_type is "blue-collar". It is ignored on white-collar positions.
  • IDs must be unique within a position; duplicates return 400.
  • Unknown IDs return 400.
  • An empty array (or omitting the field) means the agent will not gather any documents and will close the conversation right after the interview.
  • The catalog of supported IDs will grow over time. Custom prompts, file-type overrides, and bespoke extraction sets are not exposed via the API in this preview.

Result payload

Each gathered document returns an extracted_data map. Inside that map, every entry is one of three shapes depending on the field's sensitivity:

  • Non-PII: { "value": "..." } — the value is returned inline.
  • PII text: { "masked_value": "...", "document_id": "..." } — only a masked preview is returned inline; the full value is gated behind the access endpoint.
  • PII media (the captured file or any image-like field): { "document_id": "...", "redacted_url": "..." } — a long-lived URL to the redacted rendition is returned inline; the unredacted file is gated behind the access endpoint.

The fields that get extracted, and which of these three shapes each one uses, are controlled by Hirevoice per document type. Treat the map as additive and tolerate new keys appearing. A field's value (or the entire extracted entry) may be null when it could not be found or could not be read confidently.

Once the interview completes, gathered documents are reported on the interview's result.documents map, keyed by the document type ID you listed in document_gathering. result.documents is a new field added to the interview payload returned by GET /api/integration/v1/candidates/{candidate_id} and the interview.completed webhook — it sits next to the existing result fields and is only populated for blue-collar interviews. White-collar interviews do not include result.documents.

In context, the relevant slice of the candidate response looks like this:

{
  "id": "f3efbe2f-0dc1-424d-a57c-0f75e74fdc34",
  "company_candidate_uuid": "ext-cand-0099",
  "interviews": [
    {
      "position_id": "9e36a0df-2bf4-4f95-92f8-e74d8a22d2aa",
      "company_position_uuid": "ext-pos-bc-001",
      "status": "completed",
      "result": {
        "documents": { "...": "see below" }
      }
    }
  ]
}

The documents map itself:

{
  "documents": {
    "national_id": {
      "received_at": "2026-05-08T10:14:22+00:00",
      "extracted_data": {
        "file": {
          "document_id": "doc_01HZX7Q4M2YV9F0K3R8B6E2A1C",
          "redacted_url": "https://files.hirevoice.ai/redacted/doc_01HZX7Q4M2YV9F0K3R8B6E2A1C.jpg"
        },
        "id_number": {
          "masked_value": "X****567Z",
          "document_id": "doc_01HZX7QID0NUM1234567ABCDEF"
        },
        "full_name": {
          "masked_value": "A** L******",
          "document_id": "doc_01HZX7QFULLNAME9876543210AB"
        },
        "country": { "value": "ES" },
        "expiry_date": { "value": "2031-04-12" }
      }
    },
    "forklift_license": {
      "received_at": "2026-05-08T10:15:01+00:00",
      "extracted_data": {
        "file": {
          "document_id": "doc_01HZX7QABCD2YV9F0K3R8B6E2A",
          "redacted_url": "https://files.hirevoice.ai/redacted/doc_01HZX7QABCD2YV9F0K3R8B6E2A.pdf"
        },
        "license_number": {
          "masked_value": "FL-***213",
          "document_id": "doc_01HZX7QLIC0001ABCDEF1234567"
        },
        "expiry_date": null
      }
    },
    "work_permit": null
  }
}
  • A null document value means the document was optional and the candidate skipped it.
  • document_ids are stable for the lifetime of the resource and scoped to your company — safe to persist alongside your candidate record.
  • redacted_url is long-lived and safe to embed in internal review UIs.

Fetching unredacted PII

Every document_id — whether it points to a media file or a single text value — is exchanged for its protected content through one audited, short-lived endpoint:

POST /api/integration/v1/documents/{document_id}/access

The response shape depends on the resource type behind the document_id:

Media (returns a single-use signed URL):

{
  "document_id": "doc_01HZX7Q4M2YV9F0K3R8B6E2A1C",
  "kind": "media",
  "mime_type": "image/jpeg",
  "signed_url": "https://files.hirevoice.ai/...signed...",
  "expires_at": "2026-05-08T10:20:22+00:00"
}

Text value (returns the unredacted value inline):

{
  "document_id": "doc_01HZX7QID0NUM1234567ABCDEF",
  "kind": "value",
  "value": "X1234567Z"
}

Rules:

  • signed_url is single-use and expires in a few minutes — call this endpoint each time you need the file rather than caching the URL.
  • Each access call is logged for audit purposes; only request access when you have a concrete reason to view the data.
  • You are responsible for downloading and persisting media on your side if you need long-term storage. Hirevoice retains the original only for the agreed retention window.

What's not in this preview

  • Customizing the WhatsApp agent's tone, scripts, or question order.
  • Document gathering on white-collar positions.
  • File types beyond image and pdf.
  • Languages beyond es, ca, en, fr, and ur.

On this page