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

# Trim a PVC voice sample

> Sets (or clears) the trim boundaries used on a sample during training. Trimming does not modify or re-upload the underlying audio file — it only marks the range that training should use.

Sets the start and end offsets (in milliseconds) that training uses from this sample — it does not re-encode or replace the uploaded file. Trimming only takes effect the next time you [train](/api-reference/pvcAPI/pvcvoiceservice/train-pvc-voice) the voice.

The `updateMask` query parameter is **required** and uses **snake\_case** field paths (for example: `?updateMask=trim_start_ms,trim_end_ms`). To clear an existing trim and use the full sample again, include the field in `updateMask` and send `null` in the body:

```json theme={"system"}
{ "trimStartMs": null, "trimEndMs": null }
```

<Note>
  Trimmed-out audio still counts toward the voice's 5 GB storage cap, but not toward the 600-second minimum required to [train](/api-reference/pvcAPI/pvcvoiceservice/train-pvc-voice) — that minimum is computed on trimmed duration.
</Note>


## OpenAPI

````yaml patch /voices/v1/pvcVoices/{voiceId}/samples/{sampleId}
openapi: 3.0.0
info:
  title: Inworld Professional Voice Cloning API
  version: v1
  contact:
    name: Inworld AI
    url: https://inworld.ai
    email: support@inworld.ai
servers:
  - url: https://api.inworld.ai
security:
  - inworld_basic: []
tags:
  - name: PvcVoiceService
paths:
  /voices/v1/pvcVoices/{voiceId}/samples/{sampleId}:
    patch:
      tags:
        - PvcVoiceService
      summary: Trim a PVC voice sample
      description: >-
        Sets (or clears) the trim boundaries used on a sample during training.
        Trimming does not modify or re-upload the underlying audio file — it
        only marks the range that training should use.
      operationId: PvcVoiceService_UpdatePvcVoiceSample
      parameters:
        - name: voiceId
          description: Voice ID that owns the sample.
          in: path
          required: true
          schema:
            type: string
        - name: sampleId
          description: >-
            Sample ID to trim, from the `sampleId` field returned by [Upload PVC
            voice
            samples](/api-reference/pvcAPI/pvcvoiceservice/upload-pvc-voice-samples)
            or [Get a PVC
            voice](/api-reference/pvcAPI/pvcvoiceservice/get-pvc-voice).
          in: path
          required: true
          schema:
            type: string
        - name: updateMask
          description: >-
            Comma-separated list of fields to update. Mask paths use
            **snake_case** field names, even though the request body uses
            camelCase: `trim_start_ms`, `trim_end_ms`. To clear an existing
            trim, include the field in the mask and send `null` (or omit it from
            the body).
          in: query
          required: true
          schema:
            type: string
            example: trim_start_ms,trim_end_ms
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PvcVoiceServiceUpdatePvcVoiceSampleBody'
            example:
              trimStartMs: 1000
              trimEndMs: 5000
        required: true
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/inworldvoicev1PvcVoiceSample'
              examples:
                trimmed:
                  summary: Sample with a trim range applied
                  value:
                    sampleId: s_9f1c2e
                    name: >-
                      workspaces/your_workspace_id/pvcVoices/my-professional-voice/samples/s_9f1c2e
                    sizeBytes: 24883220
                    durationSecs: 312.4
                    mimeType: audio/wav
                    hash: <base64-gcs-md5>
                    trimStartMs: 1000
                    trimEndMs: 5000
        '400':
          description: >-
            `trimEndMs` is not after `trimStartMs`, or the range falls outside
            the sample's duration.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rpcStatus'
        default:
          description: An unexpected error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rpcStatus'
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            curl --location --request PATCH
            'https://api.inworld.ai/voices/v1/pvcVoices/<voice-id>/samples/<sample-id>?updateMask=trim_start_ms,trim_end_ms'
            \

            --header "Authorization: Basic $INWORLD_API_KEY" \

            --header 'Content-Type: application/json' \

            --data '{
              "trimStartMs": 1000,
              "trimEndMs": 5000
            }'
        - lang: python
          label: Python
          source: >-
            import requests


            voice_id = "<voice-id>"

            sample_id = "<sample-id>"

            url =
            f"https://api.inworld.ai/voices/v1/pvcVoices/{voice_id}/samples/{sample_id}"

            headers = {
                "Authorization": "Basic <api-key>",
                "Content-Type": "application/json"
            }

            params = {"updateMask": "trim_start_ms,trim_end_ms"}

            payload = {"trimStartMs": 1000, "trimEndMs": 5000}


            response = requests.patch(url, headers=headers, params=params,
            json=payload)

            print(response.json())
        - lang: javascript
          label: JavaScript
          source: >-
            const voiceId = '<voice-id>';

            const sampleId = '<sample-id>';

            const url =
            `https://api.inworld.ai/voices/v1/pvcVoices/${voiceId}/samples/${sampleId}?updateMask=trim_start_ms,trim_end_ms`;


            const response = await fetch(url, {
              method: 'PATCH',
              headers: {
                'Authorization': 'Basic <api-key>',
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({ trimStartMs: 1000, trimEndMs: 5000 }),
            });


            const data = await response.json();

            console.log(data);
components:
  schemas:
    PvcVoiceServiceUpdatePvcVoiceSampleBody:
      type: object
      properties:
        trimStartMs:
          type: integer
          format: int32
          nullable: true
          description: >-
            Offset in milliseconds, from the start of the sample, where the
            audio used for training begins. Include `trim_start_ms` (snake_case)
            in `updateMask` to apply this field; send `null` to clear it.
        trimEndMs:
          type: integer
          format: int32
          nullable: true
          description: >-
            Offset in milliseconds, from the start of the sample, where the
            audio used for training ends. Include `trim_end_ms` (snake_case) in
            `updateMask` to apply this field; send `null` to clear it.
      description: Request message for UpdatePvcVoiceSample. `updateMask` is required.
    inworldvoicev1PvcVoiceSample:
      type: object
      properties:
        sampleId:
          type: string
          description: >-
            Sample ID. Use this value as `{sampleId}` when trimming or deleting
            the sample.
          readOnly: true
        name:
          type: string
          description: >-
            Resource name. Format:
            `workspaces/{workspace}/pvcVoices/{voice}/samples/{sample}`.
          readOnly: true
        sizeBytes:
          type: integer
          format: int64
          description: Size of the uploaded file, in bytes.
          readOnly: true
        durationSecs:
          type: number
          format: float
          description: >-
            Analyzed duration of the sample, in seconds, before any trim is
            applied.
          readOnly: true
        mimeType:
          type: string
          enum:
            - audio/wav
            - audio/webm
            - audio/mpeg
          description: Detected audio format, sniffed from the file's byte content.
          readOnly: true
        hash:
          type: string
          description: >-
            Base64-encoded MD5 of the stored object, for verifying upload
            integrity against the source file.
          readOnly: true
        trimStartMs:
          type: integer
          format: int32
          nullable: true
          description: Trim start offset in milliseconds, if set.
        trimEndMs:
          type: integer
          format: int32
          nullable: true
          description: Trim end offset in milliseconds, if set.
      description: A single uploaded audio sample belonging to a PVC voice.
    rpcStatus:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: >-
            The status code, which should be an enum value of
            [google.rpc.Code][google.rpc.Code].
        message:
          type: string
          description: >-
            A developer-facing error message, which should be in English. Any
            user-facing error message should be localized and sent in the
            [google.rpc.Status.details][google.rpc.Status.details] field, or
            localized by the client.
        details:
          type: array
          items:
            $ref: '#/components/schemas/protobufAny'
          description: >-
            A list of messages that carry the error details. There is a common
            set of message types for APIs to use.
      description: >-
        The `Status` type defines a logical error model that is suitable for
        different programming environments, including REST APIs and RPC APIs.
    protobufAny:
      type: object
      properties:
        '@type':
          type: string
          description: >-
            A URL/resource name that uniquely identifies the type of the
            serialized protocol buffer message.
      additionalProperties: {}
      description: >-
        `Any` contains an arbitrary serialized protocol buffer message along
        with a URL that describes the type of the serialized message.
  securitySchemes:
    inworld_basic:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Your [API key](../../../api-reference/introduction). Read permissions
        are required for GET endpoints. Write permissions are required for POST,
        PATCH, and DELETE endpoints.

         For Basic authentication, please populate `Basic $INWORLD_API_KEY`. You can create a key in one command with the [Inworld CLI](../../../tts/resources/inworld-cli): `inworld workspace add-key`.

````