curl --request POST 'https://api.voicecheap.ai/v1/actions/youtube_chapters_export' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"historyId":"history_20261016_001"}'
const input = {
historyId: 'history_20261016_001',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/youtube_chapters_export', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/youtube_chapters_export",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"historyId": "history_20261016_001"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
{
"data": {
"fileName": "Product-tutorial.txt",
"contentType": "text/plain; charset=utf-8",
"content": "00:00 Introduction\n00:20 Create a project\n00:40 Export your result"
}
}
Transcription
Export YouTube chapters
Export saved timestamped chapters as plain text suitable for a video description.
POST
/
v1
/
actions
/
youtube_chapters_export
curl --request POST 'https://api.voicecheap.ai/v1/actions/youtube_chapters_export' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"historyId":"history_20261016_001"}'
const input = {
historyId: 'history_20261016_001',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/youtube_chapters_export', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/youtube_chapters_export",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"historyId": "history_20261016_001"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
{
"data": {
"fileName": "Product-tutorial.txt",
"contentType": "text/plain; charset=utf-8",
"content": "00:00 Introduction\n00:20 Create a project\n00:40 Export your result"
}
}
Export saved timestamped chapters as plain text suitable for a video description.
Required permissions:
POST https://api.voicecheap.ai/v1/actions/youtube_chapters_export
Authentication and permissions
string
required
Send a VoiceCheap API key in this header. Authorization: Bearer with the same API key is also supported. OAuth access tokens are accepted only by
MCP, not by this REST endpoint.
transcription:read.
An active paid subscription is required. Permissions do not change team roles, resource ownership, media credits, or plan limits.
Parameters
string
required
Text value.Minimum length: 1. Maximum length: 160. Pattern:
^[A-Za-z0-9_-]+$.Complete input schema
Complete input schema
The JSON Schema below preserves the exact field names, nested types, defaults, bounds, and accepted values exposed by discovery. Additional cross-field rules are listed in the operation notes.
{
"type": "object",
"properties": {
"historyId": {
"type": "string",
"minLength": 1,
"maxLength": 160,
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": ["historyId"],
"additionalProperties": false
}
Request examples
Replace example resource identifiers and media keys with values returned for your account. Keep the request identifier stable when retrying the same mutation.curl --request POST 'https://api.voicecheap.ai/v1/actions/youtube_chapters_export' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"historyId":"history_20261016_001"}'
const input = {
historyId: 'history_20261016_001',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/youtube_chapters_export', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/youtube_chapters_export",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"historyId": "history_20261016_001"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
Response
A successful first execution returns HTTP 200 with the operation result under data. A replay may return saved request state instead. The example shows one supported response, not every optional field. Saved timestamped chapter text with a sanitized .txt filename.{
"data": {
"fileName": "Product-tutorial.txt",
"contentType": "text/plain; charset=utf-8",
"content": "00:00 Introduction\n00:20 Create a project\n00:40 Export your result"
}
}
Result fields
| Field | Description |
|---|---|
data.fileName | Suggested sanitized local filename with the requested format extension. |
data.contentType | MIME type for the exported text. |
data.content | Complete exported text as a JSON string. |
Operation notes
- Requires a paid subscription and the action permission. The actor’s personal tool plan is rechecked at execution; saved tools and upload references belong to that actor, including when the credential is associated with a team.
- A successful action uses one shared monthly API/MCP call. Beginner allows 500, Starter 5,000 and Creator 25,000 calls/month; Pro, Scale and Enterprise have no monthly ceiling. Per-minute limits still apply: 30, 60, 120, 180, 300 and 600 respectively. Tool generation allowances are separate.
- content is response.text from owned YouTube chapter history, ready to save locally or paste into a video description.
- Returns text inside JSON. Save the content string to the returned fileName; this action does not return binary media or a public transcript URL.
- The output filename is sanitized from the saved source name and bounded to a 180-character basename. Export reads existing history and does not consume a source upload or daily tool allowance.
Usage
Each successful invocation consumes one monthly API/MCP call. Media credits and the operation’s own generation allowances also apply.Errors
| HTTP status | Code | Meaning or recovery |
|---|---|---|
| 400 | CREDENTIAL_IN_QUERY | Credentials were supplied in an access_token or api_key query parameter. Send credentials in headers. |
| 400 | VALIDATION_ERROR | Arguments do not satisfy the action schema, or an unknown argument was supplied. |
| 401 | API_KEY_EXPIRED | The API key has expired. |
| 401 | INVALID_API_KEY | Provide a valid, unexpired API key. |
| 401 | INVALID_CREDENTIAL | The Authorization header is malformed or conflicts with x-api-key. |
| 401 | MISSING_CREDENTIAL | No usable header credential was supplied, or it exceeded 4096 characters. |
| 401 | USER_NOT_FOUND | The credential’s account no longer exists. |
| 403 | AMBIGUOUS_TEAM_API_KEY | The credential’s user belongs to more than one team, so the billing context is ambiguous. |
| 403 | INSUFFICIENT_SCOPE | The API key or MCP connection lacks the required action permission. |
| 403 | INTEGRATION_PLAN_UNSUPPORTED | The account’s integration limits could not be verified. |
| 403 | PAID_SUBSCRIPTION_REQUIRED | The authenticated actor no longer has a paid subscription when this tool action executes. |
| 403 | SUBSCRIPTION_REQUIRED | Use an active paid subscription. |
| 403 | TEAM_OWNER_NOT_FOUND | The effective team owner account could not be found. |
| 404 | YOUTUBE_CHAPTERS_HISTORY_NOT_FOUND | The corresponding saved history item does not exist for this actor. |
| 429 | INTEGRATION_MONTHLY_LIMIT_REACHED | Used and pending calls have reached the shared monthly API/MCP allowance. |
| 429 | INTEGRATION_RATE_LIMIT_REACHED | The account has reached its per-minute integration limit; inspect retryAfterSeconds. |
| 500 | INTERNAL_ERROR | Saved export content could not be read. |
| 503 | SERVER_RESTARTING | The server is restarting. Retry shortly and keep the same request identifier for a mutation. |
{
"code": "INSUFFICIENT_SCOPE",
"message": "This credential does not permit the requested action.",
"status": 403,
"details": {
"requiredScopes": ["transcription:read"]
}
}
Was this page helpful?

