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

# Enroll a User

> Create a voiceprint for a user from a voice recording. Returns 202 immediately; result delivered via webhook.

## Overview

Enrollment is the process of creating a voiceprint — a mathematical representation of a user's unique vocal characteristics — from a voice recording. Once enrolled, a user can be verified at any time by submitting a new recording and comparing it against their stored voiceprint.

Enrollment is **asynchronous**. You submit the request, receive a 202 Accepted immediately, and Voxmind delivers the result (including voiceprint quality score and status) to your configured callback URL when processing is complete. This typically takes 1–3 seconds.

<Note>
  A user's `external_id` is your identifier — use whatever format you use in your own system (UUID, integer, email, etc.). Voxmind doesn't validate the format; it just stores and returns it. Consistency is what matters: the same `external_id` must be used in all future verification calls for this user.
</Note>

## Path Parameters

<ParamField path="orgId" type="string" required>
  Your organisation's unique identifier. Found in your dashboard or returned by `GET /organisations/{orgId}`.
</ParamField>

## Request Body

<ParamField body="voice_data" type="string (binary)" required>
  The user's voice recording, base64-encoded. Accepted formats: WAV, MP3. Minimum 3 seconds of speech; 5 seconds recommended for optimal accuracy. Minimum sample rate: 16kHz.
</ParamField>

<ParamField body="request_uuid" type="string (UUID)" required>
  A unique identifier you generate for this request. Voxmind returns this value in the webhook callback so you can match the async result to the originating request. Use UUID v4.
</ParamField>

<ParamField body="external_id" type="string" required>
  Your user's identifier in your system. This is the key used to associate verifications with this enrollment. Must be consistent across all calls for the same user.
</ParamField>

<ParamField body="language" type="string" default="en-UK">
  The primary language of the audio, in `[ISO 639-1]-[ISO 3166-1 alpha-2]` format (e.g., `en-UK`, `fr-FR`, `de-DE`, `es-ES`). Voxmind is language-agnostic — users can verify in any language after enrolling — but specifying the language improves phoneme boundary detection accuracy. See [Language Support](/guides/language-support) for all supported values.
</ParamField>

<ParamField body="device_fingerprint" type="string">
  Optional. A unique identifier for the device the user is using during enrollment. Used for device-level fraud analytics and to associate voiceprints with specific hardware.
</ParamField>

<ParamField body="device_type" type="integer">
  Optional. An integer representing the category of device. `0` = unknown, `1` = mobile phone, `2` = desktop/laptop, `3` = IP phone/desk phone. Used for analytics and to contextualise match scores — audio characteristics vary across device types.
</ParamField>

## Response

<ResponseField name="callback_url" type="string">
  The webhook URL Voxmind will call with the enrollment result. This is your configured callback URL pulled from organisation settings.
</ResponseField>

<ResponseField name="message" type="string">
  A human-readable confirmation that the request was accepted and is being processed.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.voxmind.ai/organisations/42/enrollments \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{
      "voice_data": "UklGRiQAAABXQVZFZm10IBAAAA...",
      "request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "external_id": "user_98765",
      "language": "en-UK",
      "device_type": 1
    }'
  ```

  ```python Python theme={null}
  import requests, base64, uuid

  with open("user_voice.wav", "rb") as f:
      voice_b64 = base64.b64encode(f.read()).decode("utf-8")

  resp = requests.post(
      "https://api.voxmind.ai/organisations/42/enrollments",
      headers={
          "Authorization": "Bearer YOUR_API_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "voice_data": voice_b64,
          "request_uuid": str(uuid.uuid4()),
          "external_id": "user_98765",
          "language": "en-UK",
      }
  )
  print(resp.status_code, resp.json())
  ```

  ```javascript Node.js theme={null}
  const fs = require("fs");
  const { randomUUID } = require("crypto");

  const voiceData = fs.readFileSync("user_voice.wav").toString("base64");

  const response = await fetch(
    "https://api.voxmind.ai/organisations/42/enrollments",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_API_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        voice_data: voiceData,
        request_uuid: randomUUID(),
        external_id: "user_98765",
        language: "en-UK",
      }),
    }
  );
  console.log(await response.json());
  ```
</RequestExample>

<ResponseExample>
  ```json 202 Accepted theme={null}
  {
    "callback_url": "https://yourapp.com/webhooks/voxmind",
    "message": "Your request has been accepted and is being processed"
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "code": 400,
    "message": "Validation failed",
    "errors": [
      {
        "field": "voice_data",
        "message": "This field is required"
      },
      {
        "field": "request_uuid",
        "message": "Must be a valid UUID v4"
      }
    ]
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "code": 401,
    "message": "Invalid or expired authentication credentials"
  }
  ```
</ResponseExample>
