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

# Créer une campagne

> Crée une nouvelle campagne de recrutement avec génération automatique ou personnalisation des questions, des messages et de la voix de l'agent IA

## Corps de la requête

### Champs requis

<ParamField body="job_title" type="string" required>
  Titre du poste à pourvoir
</ParamField>

<ParamField body="contract_type" type="string" required>
  Type de contrat proposé

  Valeurs possibles (alignées sur le dashboard) :

  * `CDI` - Contrat à durée indéterminée
  * `CDD` - Contrat à durée déterminée
  * `Stage` - Convention de stage
  * `Intérim` - Mission d'intérim
  * `Contrat d'apprentissage`
  * `Contrat de professionnalisation`
  * `Freelance` - Mission freelance
</ParamField>

<ParamField body="job_description" type="string" required>
  Description détaillée du poste, des responsabilités et du profil recherché
</ParamField>

### Métadonnées (optionnel)

<ParamField body="additional_info" type="string">
  Informations complémentaires sur le poste ou l'entreprise
</ParamField>

<ParamField body="client_name" type="string">
  Nom de l'entreprise cliente (sera utilisé lors des appels). Par défaut, le nom de l'agence.
</ParamField>

<ParamField body="language" type="string" default="fr">
  Langue de la campagne (agent vocal, emails, SMS, interface candidat)

  Valeurs possibles : `fr`, `en`, `es`
</ParamField>

### Questions personnalisées (optionnel)

<ParamField body="questions" type="array">
  Questions personnalisées d'entretien (maximum 10).

  Si non fourni, 6 questions sont générées automatiquement par IA depuis la description du poste.
</ParamField>

<ParamField body="question_weights" type="array">
  Poids associés à chaque question (requis si `questions` est fourni). Doit avoir la même longueur que `questions`.

  Valeurs possibles pour chaque poids : `0`, `0.5`, `1`, `1.5`, `2`
</ParamField>

<ParamField body="question_binary_evaluations" type="array">
  Évaluation binaire (oui/non) par question (optionnel, requis avoir la même longueur que `questions` si fourni). Chaque élément est un booléen.
</ParamField>

### Voix de l'agent IA (optionnel)

<ParamField body="override_agent_id" type="string">
  ID de la voix à utiliser. Récupérer la liste via [`GET /api/v1/voices`](/api-reference/account/list-voices).

  Accepte soit un `agent_id` (voix par défaut VoiceHire) soit un `voice_id` (clone d'agence).

  Le drapeau `is_voice_clone` est déduit automatiquement côté backend.
</ParamField>

### Toggles d'entretien (optionnel)

<ParamField body="enable_salary_question" type="string" default="Non">
  Format de la question sur les prétentions salariales

  Valeurs possibles : `Non`, `Annuelles`, `Mensuelles`, `Horaires`
</ParamField>

<ParamField body="enable_job_search_question" type="boolean" default="false">
  Demander si le candidat est en recherche active
</ParamField>

<ParamField body="enable_availability_question" type="boolean" default="true">
  Demander la date de disponibilité du candidat
</ParamField>

<ParamField body="enable_introduction_question" type="boolean" default="true">
  Demander au candidat de se présenter
</ParamField>

<ParamField body="enable_engage" type="boolean">
  VoiceHire Engage — message d'accroche en début d'entretien.

  Si non fourni, hérite du défaut de l'agence.
</ParamField>

<ParamField body="engage_message" type="string">
  Texte personnalisé d'accroche (350 caractères max). Utilisé uniquement si `enable_engage = true`.
</ParamField>

<ParamField body="enable_recapInterview" type="boolean">
  Récap interview au candidat. Si non fourni, hérite du défaut de l'agence.
</ParamField>

<ParamField body="enable_recapJob" type="boolean">
  Récap offre au candidat. Si non fourni, hérite du défaut de l'agence.
</ParamField>

<ParamField body="recap_job_message" type="string">
  Texte personnalisé du récap offre (350 caractères max). Utilisé uniquement si `enable_recapJob = true`.
</ParamField>

<ParamField body="enable_close" type="boolean">
  VoiceHire Close — message de clôture personnalisé. Si non fourni, hérite du défaut de l'agence.
</ParamField>

<ParamField body="close_message" type="string">
  Texte personnalisé de clôture (350 caractères max). Utilisé uniquement si `enable_close = true`.
</ParamField>

### Sélection automatique (optionnel)

<ParamField body="automatic_selection_threshold" type="number">
  Score minimum pour la sélection automatique des candidats.

  Valeurs possibles : `8.0`, `8.5`, `9.0`, `9.5`, `10.0`. `null` désactive.
</ParamField>

### Test linguistique (optionnel)

<ParamField body="language_test_mode" type="string" default="none">
  Mode test linguistique pendant l'entretien

  Valeurs possibles : `none`, `english`, `spanish`, `italian`, `german`, `chinese`, `portuguese`, `arabic`
</ParamField>

<ParamField body="custom_language_question" type="string">
  Question additionnelle pour le test linguistique. Nécessite `language_test_mode != "none"`.

  Le backend la traduit automatiquement vers la langue cible via OpenAI.
</ParamField>

## Réponse

<ResponseExample>
  ```json theme={null}
  {
    "campaign_id": "abc123",
    "candidate_link": "https://app.voicehire.io/apply/abc123",
    "status": "active",
    "questions_generated": 6
  }
  ```
</ResponseExample>

<ResponseField name="campaign_id" type="string" required>
  Identifiant unique de la campagne créée
</ResponseField>

<ResponseField name="candidate_link" type="string" required>
  Lien à partager avec les candidats pour postuler
</ResponseField>

<ResponseField name="status" type="string" required>
  Statut de la campagne (toujours `active` à la création)
</ResponseField>

<ResponseField name="questions_generated" type="integer" required>
  Nombre de questions utilisées pour l'entretien (questions fournies ou générées par IA)
</ResponseField>

## Exemple de requête

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.voicehire.io/api/v1/campaigns/create \
    -H "X-API-Key: vh_live_XXXXXXXXXXXXX" \
    -H "Content-Type: application/json" \
    -d '{
      "job_title": "Développeur Full Stack",
      "contract_type": "CDI",
      "job_description": "Nous recherchons un développeur Full Stack expérimenté...",
      "client_name": "TechCorp",
      "language": "fr",
      "questions": [
        "Quelle est votre expérience avec React et Node.js ?",
        "Avez-vous déjà travaillé en méthodologie Agile ?"
      ],
      "question_weights": [2, 1.5],
      "question_binary_evaluations": [false, true],
      "enable_salary_question": "Annuelles",
      "enable_close": true,
      "close_message": "Merci pour votre temps, nous reviendrons vers vous sous 48h.",
      "automatic_selection_threshold": 8.5
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://app.voicehire.io/api/v1/campaigns/create",
      headers={
          "X-API-Key": "vh_live_XXXXXXXXXXXXX",
          "Content-Type": "application/json"
      },
      json={
          "job_title": "Développeur Full Stack",
          "contract_type": "CDI",
          "job_description": "Nous recherchons un développeur Full Stack expérimenté...",
          "client_name": "TechCorp",
          "language": "fr",
          "questions": [
              "Quelle est votre expérience avec React et Node.js ?",
              "Avez-vous déjà travaillé en méthodologie Agile ?"
          ],
          "question_weights": [2, 1.5],
          "question_binary_evaluations": [False, True],
          "enable_salary_question": "Annuelles",
          "enable_close": True,
          "close_message": "Merci pour votre temps, nous reviendrons vers vous sous 48h.",
          "automatic_selection_threshold": 8.5
      }
  )
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const response = await axios.post(
    'https://app.voicehire.io/api/v1/campaigns/create',
    {
      job_title: 'Développeur Full Stack',
      contract_type: 'CDI',
      job_description: 'Nous recherchons un développeur Full Stack expérimenté...',
      client_name: 'TechCorp',
      language: 'fr',
      questions: [
        'Quelle est votre expérience avec React et Node.js ?',
        'Avez-vous déjà travaillé en méthodologie Agile ?'
      ],
      question_weights: [2, 1.5],
      question_binary_evaluations: [false, true],
      enable_salary_question: 'Annuelles',
      enable_close: true,
      close_message: 'Merci pour votre temps, nous reviendrons vers vous sous 48h.',
      automatic_selection_threshold: 8.5
    },
    {
      headers: {
        'X-API-Key': 'vh_live_XXXXXXXXXXXXX',
        'Content-Type': 'application/json'
      }
    }
  );
  ```
</CodeGroup>

## Codes d'erreur

| Code | `code`                                        | Description                                                         |
| ---- | --------------------------------------------- | ------------------------------------------------------------------- |
| 400  | `MISSING_REQUIRED_FIELDS`                     | Champs requis manquants                                             |
| 400  | `INVALID_CONTRACT_TYPE`                       | Type de contrat invalide                                            |
| 400  | `INVALID_LANGUAGE`                            | Langue non supportée (utiliser `fr`, `en` ou `es`)                  |
| 400  | `TOO_MANY_QUESTIONS`                          | Plus de 10 questions fournies                                       |
| 400  | `MISSING_QUESTION_WEIGHTS`                    | `question_weights` manquant alors que `questions` est fourni        |
| 400  | `WEIGHTS_MISMATCH`                            | Longueur de `question_weights` différente de `questions`            |
| 400  | `INVALID_WEIGHT_VALUE`                        | Poids hors de la plage `[0, 0.5, 1, 1.5, 2]`                        |
| 400  | `BINARY_EVALUATIONS_MISMATCH`                 | Longueur de `question_binary_evaluations` différente de `questions` |
| 400  | `INVALID_AUTOMATIC_SELECTION_THRESHOLD`       | Seuil hors de la plage `[8.0, 8.5, 9.0, 9.5, 10.0]`                 |
| 400  | `MESSAGE_TOO_LONG`                            | Un message dépasse 350 caractères                                   |
| 400  | `INVALID_OVERRIDE_AGENT_ID`                   | Voix introuvable ou non accessible par l'agence                     |
| 400  | `CUSTOM_LANGUAGE_QUESTION_REQUIRES_TEST_MODE` | `custom_language_question` fourni sans `language_test_mode`         |
| 401  | `INVALID_API_KEY` / `MISSING_API_KEY`         | Clé API manquante ou invalide                                       |
| 402  | `INSUFFICIENT_CREDITS`                        | Crédits insuffisants pour créer une campagne                        |


## OpenAPI

````yaml POST /api/v1/campaigns/create
openapi: 3.0.3
info:
  title: VoiceHire API
  description: >
    API REST pour automatiser les campagnes de recrutement avec VoiceHire.


    ## Authentification


    L'API utilise une authentification par clé API. Vous devez inclure votre clé
    API dans l'en-tête `X-API-Key` de chaque requête.


    ```

    X-API-Key: vh_live_XXXXXXXXXXXXX

    ```


    ## Format des réponses


    Toutes les réponses sont au format JSON. Les erreurs suivent un format
    standardisé :


    ```json

    {
      "error": {
        "code": "ERROR_CODE",
        "message": "Description de l'erreur",
        "details": {}
      }
    }

    ```


    ## Limites


    - Les numéros de téléphone doivent être des numéros français (06 ou 07)

    - Maximum 100 candidats par requête d'ajout

    - Les campagnes génèrent automatiquement 6 questions d'entretien
  version: 1.0.0
  contact:
    name: Support VoiceHire
    email: support@voicehire.io
    url: https://www.voicehire.io
servers:
  - url: https://app.voicehire.io
    description: Production
  - url: http://localhost:8080
    description: Développement local
security:
  - ApiKeyAuth: []
tags:
  - name: Campagnes
    description: Gestion des campagnes de recrutement
  - name: Candidats
    description: Gestion des candidats
  - name: Compte
    description: Informations du compte
paths:
  /api/v1/campaigns/create:
    post:
      tags:
        - Campagnes
      summary: Créer une campagne
      description: >
        Crée une nouvelle campagne de recrutement avec génération automatique de
        6 questions d'entretien.

        Les questions sont générées par IA en fonction de la description du
        poste.
      operationId: createCampaign
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignCreateRequest'
            examples:
              developpeur:
                summary: Développeur Full Stack
                value:
                  job_title: Développeur Full Stack Node.js/React
                  contract_type: CDI
                  job_description: >
                    Nous recherchons un développeur Full Stack passionné par les
                    technologies web modernes.


                    Responsabilités:

                    - Développer des applications web avec Node.js et React

                    - Participer à la conception de l'architecture

                    - Collaborer avec l'équipe produit


                    Compétences requises:

                    - 3+ ans d'expérience

                    - Maîtrise de Node.js, React

                    - Bases de données SQL/NoSQL
                  client_name: TechCorp SAS
                  enable_salary_question: true
              commercial:
                summary: Commercial B2B
                value:
                  job_title: Commercial B2B Senior
                  contract_type: CDI
                  job_description: >
                    Recherche commercial B2B expérimenté pour développer notre
                    portefeuille clients.


                    Mission:

                    - Prospection et développement commercial

                    - Gestion d'un portefeuille clients

                    - Négociation de contrats
                  enable_salary_question: true
      responses:
        '201':
          description: Campagne créée avec succès
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignCreateResponse'
              example:
                campaign_id: CAMP-20250701-ABC123
                candidate_link: https://app.voicehire.io/apply/CAMP-20250701-ABC123
                status: active
                questions_generated: 6
                questions_source: ai
        '400':
          description: Données invalides
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missing_fields:
                  value:
                    error:
                      code: MISSING_REQUIRED_FIELDS
                      message: Required fields are missing
                      details:
                        missing_fields:
                          - job_title
                          - contract_type
                invalid_contract:
                  value:
                    error:
                      code: INVALID_CONTRACT_TYPE
                      message: Invalid contract type
                      details:
                        valid_types:
                          - CDI
                          - CDD
                          - Stage
                          - Intérim
                          - Contrat d'apprentissage
                          - Contrat de professionnalisation
                          - Freelance
        '402':
          description: Crédits insuffisants
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INSUFFICIENT_CREDITS
                  message: No credits available
                  details:
                    credits_available: 0
components:
  schemas:
    CampaignCreateRequest:
      type: object
      required:
        - job_title
        - contract_type
        - job_description
      properties:
        job_title:
          type: string
          description: Titre du poste
          example: Développeur Full Stack Node.js/React
        contract_type:
          type: string
          enum:
            - CDI
            - CDD
            - Stage
            - Intérim
            - Contrat d'apprentissage
            - Contrat de professionnalisation
            - Freelance
          description: Type de contrat (aligné sur les valeurs du dashboard)
          example: CDI
        job_description:
          type: string
          description: Description détaillée du poste
          example: |
            Nous recherchons un développeur Full Stack passionné...
        additional_info:
          type: string
          description: Informations complémentaires
          example: Stack technique Node.js, React, PostgreSQL
        client_name:
          type: string
          description: >-
            Nom de l'entreprise cliente (optionnel, utilise le nom de l'agence
            par défaut)
          example: TechCorp SAS
        language:
          type: string
          enum:
            - fr
            - en
            - es
          description: Langue de la campagne (agent vocal, emails, SMS, interface candidat)
          default: fr
          example: fr
        questions:
          type: array
          maxItems: 10
          description: >-
            Questions personnalisées d'entretien. Si fourni, `question_weights`
            est requis.
          items:
            type: string
        question_weights:
          type: array
          description: >-
            Poids de chaque question. Doit avoir la même longueur que
            `questions`.
          items:
            type: number
            enum:
              - 0
              - 0.5
              - 1
              - 1.5
              - 2
        question_binary_evaluations:
          type: array
          description: >-
            Évaluation binaire (oui/non) par question. Doit avoir la même
            longueur que `questions`.
          items:
            type: boolean
        enable_salary_question:
          type: string
          enum:
            - Non
            - Annuelles
            - Mensuelles
            - Horaires
          description: Format de la question sur les prétentions salariales
          default: Non
        enable_job_search_question:
          type: boolean
          description: Demander si le candidat est en recherche active
          default: false
        enable_availability_question:
          type: boolean
          description: Demander la date de disponibilité du candidat
          default: true
        enable_introduction_question:
          type: boolean
          description: Demander au candidat de se présenter
          default: true
        enable_engage:
          type: boolean
          description: >-
            VoiceHire Engage — message d'accroche en début d'entretien (défaut
            hérité de l'agence)
        engage_message:
          type: string
          maxLength: 350
          description: Message personnalisé d'accroche (utilisé si `enable_engage = true`)
        enable_recapInterview:
          type: boolean
          description: Récap interview au candidat (défaut hérité de l'agence)
        enable_recapJob:
          type: boolean
          description: Récap offre au candidat (défaut hérité de l'agence)
        recap_job_message:
          type: string
          maxLength: 350
          description: >-
            Message personnalisé du récap offre (utilisé si `enable_recapJob =
            true`)
        enable_close:
          type: boolean
          description: VoiceHire Close — message de clôture (défaut hérité de l'agence)
        close_message:
          type: string
          maxLength: 350
          description: Message personnalisé de clôture (utilisé si `enable_close = true`)
        automatic_selection_threshold:
          type: number
          enum:
            - 8
            - 8.5
            - 9
            - 9.5
            - 10
          nullable: true
          description: >-
            Score minimum pour la sélection automatique des candidats. `null`
            désactive.
        override_agent_id:
          type: string
          description: >
            Voix de l'agent IA. Récupérer la liste via `GET /api/v1/voices`.

            Accepte soit un `agent_id` (voix par défaut VoiceHire) soit un
            `voice_id` (clone d'agence).

            Le drapeau `is_voice_clone` est déduit automatiquement côté backend.
        language_test_mode:
          type: string
          enum:
            - none
            - english
            - spanish
            - italian
            - german
            - chinese
            - portuguese
            - arabic
          default: none
          description: Mode test linguistique pendant l'entretien
        custom_language_question:
          type: string
          description: >
            Question additionnelle pour le test linguistique. Nécessite
            `language_test_mode != "none"`.

            Le backend la traduit automatiquement vers la langue cible.
    CampaignCreateResponse:
      type: object
      properties:
        campaign_id:
          type: string
          description: Identifiant de la campagne créée
          example: CAMP-20250701-ABC123
        candidate_link:
          type: string
          format: uri
          description: Lien à partager avec les candidats
          example: https://app.voicehire.io/apply/CAMP-20250701-ABC123
        status:
          type: string
          description: Statut initial de la campagne
          example: active
        questions_generated:
          type: integer
          description: Nombre de questions générées
          example: 6
        questions_source:
          type: string
          enum:
            - ai
            - default
          description: Source des questions (IA ou défaut)
          example: ai
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Code d'erreur machine-readable
              example: MISSING_API_KEY
            message:
              type: string
              description: Message d'erreur human-readable
              example: API key is required
            details:
              type: object
              description: Détails supplémentaires sur l'erreur
              additionalProperties: true
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Clé API au format vh_live_XXXXX

````