> ## Documentation Index
> Fetch the complete documentation index at: https://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.

Offsets are in milliseconds. Trimming only takes effect the next time you [train](https://docs.inworld.ai/api-reference/pvcAPI/pvcvoiceservice/train-pvc-voice.md) 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
{ "trimStartMs": null, "trimEndMs": null }
```

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

## API reference

**Endpoint:** `PATCH https://api.inworld.ai/voices/v1/pvcVoices/{voiceId}/samples/{sampleId}`

### Authorization

- `Authorization` (string; required) — 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](../../../developer-tools/inworld-cli): `inworld workspace add-key`.

### Path parameters

- `voiceId` (string; required) — Voice ID that owns the sample.
- `sampleId` (string; required) — Sample ID to trim, from the `sampleId` field returned by [Upload PVC voice samples](https://docs.inworld.ai/api-reference/pvcAPI/pvcvoiceservice/upload-pvc-voice-samples.md) or [Get a PVC voice](https://docs.inworld.ai/api-reference/pvcAPI/pvcvoiceservice/get-pvc-voice.md).

### Query parameters

- `updateMask` (string; required) — 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).

### Request body

Content type: `application/json`

- `trimStartMs` (integer) — 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` (integer) — 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.

#### Request example

```json
{
  "trimStartMs": 1000,
  "trimEndMs": 5000
}
```

### Response

Status: `200`. Content type: `application/json`.

- `sampleId` (string) — Sample ID. Use this value as `{sampleId}` when trimming or deleting the sample.
- `name` (string) — Resource name. Format: `workspaces/{workspace}/pvcVoices/{voice}/samples/{sample}`.
- `sizeBytes` (integer) — Size of the uploaded file, in bytes.
- `durationSecs` (number) — Analyzed duration of the sample, in seconds, before any trim is applied.
- `mimeType` (enum<string>; options: "audio/wav", "audio/webm", "audio/mpeg") — Detected audio format, sniffed from the file's byte content.
- `hash` (string) — Base64-encoded MD5 of the stored object, for verifying upload integrity against the source file.
- `trimStartMs` (integer) — Trim start offset in milliseconds, if set.
- `trimEndMs` (integer) — Trim end offset in milliseconds, if set.

### Response examples

#### 200: trimmed

```json
{
  "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: default_response

```json
{
  "code": 0,
  "message": "string",
  "details": [
    {
      "@type": "string"
    }
  ]
}
```

#### default: default_response

```json
{
  "code": 0,
  "message": "string",
  "details": [
    {
      "@type": "string"
    }
  ]
}
```

### Code examples

#### cURL

```bash
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
}'
```

#### Python

```python
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())
```

#### JavaScript

```javascript
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);
```
