npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@theproductivepixel/aittsm

v1.2.1

Published

MCP stdio server for AI TTS Microservice — connects AI agents, IDEs, and MCP-compatible clients to the unified TTS API via tool calls

Readme

@theproductivepixel/aittsm

npm license

MCP (Model Context Protocol) stdio server for AI TTS Microservice. Connects AI agents, IDEs, and any MCP-compatible client to the unified TTS API via tool calls.

Install

npm install -g @theproductivepixel/aittsm

Setup

export AITTSM_API_KEY=tts_your_api_key_here

Get your API key from aitts.theproductivepixel.com/dashboard/api.

Usage

Claude Desktop

{
  "mcpServers": {
    "aitts": {
      "command": "npx",
      "args": ["@theproductivepixel/aittsm"],
      "env": { "AITTSM_API_KEY": "tts_your_api_key_here" }
    }
  }
}

Cursor / Windsurf

{
  "aitts": {
    "command": "npx",
    "args": ["@theproductivepixel/aittsm"],
    "env": { "AITTSM_API_KEY": "tts_your_api_key_here" }
  }
}

Direct CLI

aittsm

Tools (34)

Voice & Generation

| Tool | Permission | Bucket | Description | |------|-----------|--------|-------------| | search_voices | voices:list | read | Search available TTS voices | | generate_speech | tts:generate | generate | Generate TTS audio | | get_job_status | tts:status | read | Check job status and metadata | | get_audio_link | tts:status | read | Get signed download URL |

Jobs

| Tool | Permission | Bucket | Description | |------|-----------|--------|-------------| | list_jobs | jobs:read | read | List jobs with pagination | | get_job_text | jobs:read | read | Get input text of a job | | update_job_metadata | jobs:write | generate | Update tags/collection | | delete_job_audio | jobs:write | generate | Delete stored audio |

Shares

| Tool | Permission | Bucket | Description | |------|-----------|--------|-------------| | create_share | shares:write | generate | Create share link | | list_shares | shares:read | read | List active shares | | get_share | shares:read | read | Get full share details | | update_share | shares:write | generate | Update share settings | | revoke_share | shares:write | generate | Revoke a share | | bulk_revoke_shares | shares:write | generate | Revoke multiple shares | | toggle_share_permanent | shares:write | generate | Toggle permanent status | | update_track_order | shares:write | generate | Reorder tracks |

Access Codes & QR

| Tool | Permission | Bucket | Description | |------|-----------|--------|-------------| | create_access_codes | shares:write | generate | Create access codes | | list_access_codes | shares:read | read | List codes (no raw values) | | update_access_code | shares:write | generate | Update a code | | delete_access_code | shares:write | generate | Delete a code | | export_access_codes | shares:read | read | Export as CSV format | | get_qr_code | shares:write | generate | Generate QR image |

Library & Storage

| Tool | Permission | Bucket | Description | |------|-----------|--------|-------------| | list_collections | library:read | read | List audio collections | | manage_collection | library:write | generate | Create/rename/delete collection | | list_tags | library:read | read | List tags with counts | | create_bookmark | library:write | generate | Bookmark a share | | list_bookmarks | library:read | read | List bookmarks | | delete_bookmark | library:write | generate | Delete a bookmark | | manage_bookmark_collection | library:write | generate | Manage bookmark collections | | get_storage | storage:read | read | Storage usage summary | | list_storage_items | storage:read | read | List stored items | | bulk_delete_storage | storage:write | generate | Bulk delete storage | | estimate_cost | pricing:estimate | read | Estimate credit cost | | get_usage | usage:read | read | Get balance and account type |

Examples

Async Generation Workflow

// 1. Generate audio
{
  "name": "generate_speech",
  "arguments": {
    "text": "Welcome to our podcast.",
    "voice_id": "google:en-US-Chirp3HD-Charon",
    "tags": ["podcast", "intro"]
  }
}
// Response:
// {
//   "job_id": "abc123",
//   "status": "pending",
//   ...
// }

// 2. Poll until completed
{
  "name": "get_job_status",
  "arguments": {
    "job_id": "abc123"
  }
}
// Response:
// {
//   "status": "completed",
//   "audio_bytes": 48000,
//   ...
// }

// 3. Get download URL
{
  "name": "get_audio_link",
  "arguments": {
    "job_id": "abc123"
  }
}
// Response:
// {
//   "audio_endpoint": "/api/v1/tts/abc123/audio",
//   "signed_url": "https://...",
//   ...
// }

Streaming Generation

{
  "name": "generate_speech",
  "arguments": {
    "text": "Stream this audio.",
    "voice_id": "google:en-US-Chirp3HD-Charon",
    "delivery_mode": "stream",
    "output_format": "ogg_opus",
    "idempotency_key": "unique-key-abc"
  }
}

Stream supports all 7 formats. Async supports wav, mp3, ogg_opus only.

Voice Search

{
  "name": "search_voices",
  "arguments": {
    "language": "en-US",
    "provider": "google",
    "model_type": "ultra"
  }
}

Share Workflow

// 1. Create a password-protected share from completed jobs
{
  "name": "create_share",
  "arguments": {
    "job_ids": ["job1", "job2"],
    "title": "Client Review",
    "auth_mode": "password",
    "password": "secret123",
    "allow_download": true
  }
}
// Response:
// {
//   "code": "xyz789",
//   "url": "https://aitts.theproductivepixel.com/share/audio/xyz789",
//   "item_count": 2
// }

// 2. Generate a QR code for the share
{
  "name": "get_qr_code",
  "arguments": {
    "code": "xyz789",
    "format": "png",
    "preset": "branded"
  }
}

// 3. Later, revoke access
{
  "name": "revoke_share",
  "arguments": {
    "code": "xyz789"
  }
}

Collection Management

// 1. Create a collection
{
  "name": "manage_collection",
  "arguments": {
    "action": "create",
    "name": "Podcast Episodes"
  }
}
// Response:
// {
//   "id": "col-abc",
//   "name": "Podcast Episodes"
// }

// 2. Assign jobs to it
{
  "name": "update_job_metadata",
  "arguments": {
    "job_id": "job1",
    "collection_id": "col-abc",
    "tags": ["episode-1"]
  }
}

// 3. Create a live share from the collection
{
  "name": "create_share",
  "arguments": {
    "source_type": "collection",
    "source_id": "col-abc",
    "share_mode": "live",
    "title": "All Episodes"
  }
}

Tool Reference

Complete per-tool parameter tables, response shapes, and error codes for all 34 tools.

search_voices

| Param | Type | Required | Description | |-------|------|----------|-------------| | language | string | — | Filter by language code (e.g. en-US) | | provider | string | — | Filter by provider (google, polly, kokoro) | | model_type | premium | ultra | — | Filter by model type |

Response:

{
  "voices": [
    {
      "voice_id": "google:en-US-Chirp3HD-Charon",
      "name": "Charon",
      "language": "en-US",
      "provider": "google",
      "model_type": "ultra",
      "gender": "male"
    }
  ]
}

generate_speech

| Param | Type | Required | Description | |-------|------|----------|-------------| | text | string (1–500000) | ✓ | Text to synthesize | | voice_id | string | — | Voice ID (provider:lang-Family-Name) | | delivery_mode | async | stream | — | Default: async | | model_type | premium | ultra | — | Model type | | model | string | — | Specific model ID | | speed | number (0.25–4) | — | Speaking rate multiplier | | format | text | ssml | markup | — | Input format | | speaker_type | single | multi | — | Speaker type | | voice_id_speaker_1 | string | — | Speaker 1 voice ID (required for multi) | | voice_id_speaker_2 | string | — | Speaker 2 voice ID (required for multi) | | output_format | wav | mp3 | ogg_opus | pcm | mulaw | alaw | ogg_vorbis | — | Audio format | | prompt | string | — | Ultra model guidance prompt | | webhook_url | string (URL) | — | Completion webhook (enterprise) | | metadata | object | — | Custom metadata | | sample_rate_hertz | integer | — | Output sample rate in Hz | | output_bitrate_kbps | integer | — | Bitrate (async only) | | language | string | — | Language code override | | tags | string[] | — | Library tags | | collection_id | string | — | Collection ID | | idempotency_key | string (max 256) | — | Safe retry key |

Response (async):

{
  "job_id": "uuid",
  "status": "pending",
  "poll_url": "/api/v1/tts/{job_id}",
  "audio_endpoint": "/api/v1/tts/{job_id}/audio",
  "chars_charged": 16
}

Response (stream):

{
  "job_id": "uuid",
  "status": "pending",
  "stream_url": "https://...",
  "stream_url_expires_at": "...",
  "transport_format": "ogg_opus",
  "transport_mime_type": "audio/ogg; codecs=opus",
  "transport_sample_rate_hertz": 48000,
  "chars_charged": 30
}

get_job_status

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_id | string | ✓ | Job ID to check |

Response:

{
  "job_id": "uuid",
  "status": "completed",
  "voice_id": "...",
  "model_type": "ultra",
  "provider": "google",
  "created_at": "...",
  "completed_at": "...",
  "audio_bytes": 48000,
  "output_format": "ogg_opus",
  "chars_charged": 16,
  "tags": [],
  "collection_id": null,
  "source": "api",
  "is_expired": false
}

get_audio_link

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_id | string | ✓ | Job ID |

Response:

{
  "audio_endpoint": "/api/v1/tts/{job_id}/audio",
  "signed_url": "https://...",
  "expires_at": "2026-05-08T12:00:00Z",
  "job_id": "uuid"
}

get_job_text

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_id | string | ✓ | Job ID |

Response:

{
  "text": "Hello world"
}

list_jobs

| Param | Type | Required | Description | |-------|------|----------|-------------| | page_size | integer (1–100) | — | Items per page (default 20) | | page_token | string | — | Pagination cursor | | source | api | ui | — | Filter by source | | status | completed | failed | pending | processing | — | Filter by status |

Response:

{
  "jobs": [
    {
      "job_id": "...",
      "status": "completed",
      "...": "..."
    }
  ],
  "next_page_token": "eyJ..."
}

delete_job_audio

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_id | string | ✓ | Job ID |

Response:

{
  "shares_revoked": 0,
  "storage": null
}

update_job_metadata

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_id | string | ✓ | Job ID | | tags | string[] | — | Replace tags array | | collection_id | string | null | — | Set or clear collection |

Response:

{
  "job_id": "uuid",
  "tags": ["podcast", "episode-1"],
  "collection_id": "col-abc"
}

create_share

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_ids | string[] | — | Job IDs for snapshot share | | source_type | collection | tag | — | Source type | | source_id | string | — | Source ID | | share_mode | snapshot | live | — | Share mode | | auth_mode | none | password | access_code | — | Auth mode | | password | string | — | Password (if auth_mode=password) | | title | string | — | Share title | | allow_download | boolean | — | Allow download | | include_text | boolean | — | Include text excerpts | | show_voice | boolean | — | Show voice metadata | | show_model | boolean | — | Show model metadata | | show_provider | boolean | — | Show provider metadata | | show_language | boolean | — | Show language metadata | | show_expiry | boolean | — | Show expiry metadata | | show_track_meta | boolean | — | Show track metadata | | track_titles | object | — | Custom track titles | | track_order | string[] | — | Custom track order |

Response:

{
  "code": "abc123",
  "url": "https://aitts.theproductivepixel.com/share/audio/abc123",
  "item_count": 3
}

list_shares

| Param | Type | Required | Description | |-------|------|----------|-------------| | page_size | integer (1–100) | — | Items per page | | page_token | string | — | Pagination cursor |

Response:

{
  "shares": [
    {
      "code": "...",
      "title": "...",
      "item_count": 3,
      "auth_mode": "none",
      "share_mode": "snapshot",
      "is_permanent": false,
      "created_at": "..."
    }
  ],
  "next_page_token": null
}

get_share

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code |

Response:

{
  "code": "abc123",
  "title": "Demo",
  "auth_mode": "none",
  "share_mode": "snapshot",
  "is_permanent": false,
  "allow_download": true,
  "item_count": 2,
  "created_at": "...",
  "jobs": ["..."]
}

update_share

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | title | string | — | New title | | auth_mode | none | password | access_code | — | Auth mode | | password | string | — | Password | | allow_download | boolean | — | Allow download | | share_mode | snapshot | live | — | Share mode | | include_text | boolean | — | Include text | | show_voice | boolean | — | Show voice | | show_model | boolean | — | Show model | | show_provider | boolean | — | Show provider | | show_language | boolean | — | Show language | | show_expiry | boolean | — | Show expiry | | show_track_meta | boolean | — | Show track meta | | track_titles | object | — | Track titles | | track_order | string[] | null | — | Track order or null | | source_type | collection | tag | — | Source type | | source_id | string | — | Source ID |

Response:

{
  "code": "abc123",
  "title": "Updated",
  "auth_mode": "password",
  "updated_at": "..."
}

revoke_share

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code |

Response:

{
  "revoked": true
}

bulk_revoke_shares

| Param | Type | Required | Description | |-------|------|----------|-------------| | codes | string[] (1–100) | ✓ | Share codes to revoke |

Response:

{
  "revoked_count": 3,
  "skipped": ["code-not-found"]
}

toggle_share_permanent

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code |

Response:

{
  "code": "abc123",
  "permanent": true,
  "expires_at": null
}

update_track_order

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | track_order | string[] | null | ✓ | Ordered job IDs or null to reset |

Response:

{
  "code": "abc123",
  "track_order": ["job-2", "job-1", "job-3"]
}

create_access_codes

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | count | integer (1–100) | — | Number of codes (default 1) | | label | string | — | Label or label prefix | | expires_at | string (ISO date) | — | Expiration date | | max_uses | integer (≥1) | — | Max uses per code |

Response (count=1):

{
  "id": "doc-id",
  "code": "ABCD1234EFGH",
  "code_prefix": "ABCD",
  "label": "VIP",
  "active": true,
  "created_at": "...",
  "expires_at": null,
  "max_uses": 10
}

Response (count>1):

[
  {
    "id": "doc-1",
    "code": "ABCD1111AAAA"
  },
  {
    "id": "doc-2",
    "code": "ABCD2222BBBB"
  }
]

list_access_codes

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code |

Response:

[
  {
    "id": "...",
    "code_prefix": "ABCD",
    "label": "VIP",
    "active": true,
    "uses": 3,
    "max_uses": 10,
    "created_at": "...",
    "expires_at": null,
    "last_used_at": null
  }
]

update_access_code

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | access_code_id | string | ✓ | Access code document ID | | label | string | — | New label | | active | boolean | — | Active status | | expires_at | string | null | — | New expiry or null | | max_uses | integer | null | — | New max uses or null |

Response:

{
  "id": "doc-id",
  "code_prefix": "ABCD",
  "label": "Updated",
  "active": true,
  "uses": 3,
  "max_uses": 20,
  "created_at": "2026-05-01T00:00:00Z",
  "expires_at": null,
  "last_used_at": null
}

delete_access_code

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | access_code_id | string | ✓ | Access code document ID |

Response:

{
  "deleted": true
}

export_access_codes

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code |

Response:

[
  {
    "id": "ac-1",
    "code_prefix": "AB12",
    "label": "Reviewer",
    "active": true,
    "created_at": "...",
    "expires_at": null,
    "max_uses": 10,
    "uses": 3
  }
]

get_qr_code

| Param | Type | Required | Description | |-------|------|----------|-------------| | code | string | ✓ | Share code | | format | svg | png | ✓ | Image format | | preset | clean | branded | — | Visual preset | | include_access_code | boolean | — | Embed access code in URL | | access_code | string | — | Access code to embed |

Response:

{
  "data_uri": "data:image/png;base64,...",
  "format": "png"
}

list_collections

No parameters.

Response:

{
  "collections": [
    {
      "id": "col-abc",
      "name": "Podcast Episodes",
      "created_at": "...",
      "updated_at": "..."
    }
  ]
}

manage_collection

| Param | Type | Required | Description | |-------|------|----------|-------------| | action | create | rename | delete | ✓ | Operation | | name | string | — | Name (required for create/rename) | | collection_id | string | — | ID (required for rename/delete) |

Response (create/rename):

{
  "id": "col-id",
  "name": "New Name"
}

Response (delete):

{
  "deleted": true
}

list_tags

No parameters.

Response:

{
  "tags": [
    {
      "tag": "podcast",
      "count": 12
    },
    {
      "tag": "demo",
      "count": 3
    }
  ]
}

create_bookmark

| Param | Type | Required | Description | |-------|------|----------|-------------| | share_code | string | ✓ | Share code to bookmark |

Response:

{
  "created": true
}

list_bookmarks

| Param | Type | Required | Description | |-------|------|----------|-------------| | page_size | integer (1–100) | — | Items per page | | page_token | string | — | Pagination cursor |

Response:

{
  "bookmarks": [
    {
      "id": "bm-1",
      "share_code": "xyz789",
      "title": "Shared Audio",
      "personal_title": null,
      "collection_id": null,
      "created_at": "...",
      "last_opened_at": null,
      "effective_status": "active"
    }
  ],
  "next_page_token": null
}

delete_bookmark

| Param | Type | Required | Description | |-------|------|----------|-------------| | bookmark_id | string | ✓ | Bookmark ID (share code) |

Response:

{
  "deleted": true
}

manage_bookmark_collection

| Param | Type | Required | Description | |-------|------|----------|-------------| | action | create | rename | delete | ✓ | Operation | | name | string | — | Name (required for create/rename) | | collection_id | string | — | ID (required for rename/delete) |

Response (create/rename):

{
  "id": "col-id",
  "name": "Favorites"
}

Response (delete):

{
  "deleted": true
}

get_storage

No parameters.

Response:

{
  "used_bytes": 15728640,
  "cap_bytes": 104857600,
  "remaining_bytes": 89128960,
  "pending_reclaim_bytes": 0,
  "sync_status": "healthy"
}

list_storage_items

| Param | Type | Required | Description | |-------|------|----------|-------------| | page_size | integer (1–100) | — | Items per page | | page_token | string | — | Pagination cursor |

Response:

{
  "items": [
    {
      "job_id": "uuid",
      "status": "completed",
      "audio_bytes": 48000,
      "output_format": "ogg_opus",
      "created_at": "...",
      "storage_tier": "permanent"
    }
  ],
  "next_page_token": null
}

bulk_delete_storage

| Param | Type | Required | Description | |-------|------|----------|-------------| | job_ids | string[] (1–100) | ✓ | Job IDs to delete |

Response:

{
  "deleted_count": 3,
  "skipped_count": 1,
  "skipped": [
    {
      "job_id": "uuid",
      "reason": "job_in_progress"
    }
  ]
}

estimate_cost

| Param | Type | Required | Description | |-------|------|----------|-------------| | text | string (1–500000) | ✓ | Text to estimate | | model_type | premium | ultra | — | Model type | | voice_id | string | — | Voice ID | | output_format | wav | mp3 | ogg_opus | — | Output format |

Response:

{
  "estimated_cost": 2.5,
  "chars_charged": 500,
  "model_type": "ultra",
  "provider": "google",
  "output_format": "ogg_opus"
}

get_usage

No parameters.

Response:

{
  "account_type": "standard",
  "credits_balance": 4250
}

Pagination

Paginated tools accept page_size (1–100, default 20) and page_token (opaque cursor). Results include next_page_token (null when exhausted).

Idempotency

Pass idempotency_key to generate_speech for safe retries:

  • Same key + same body → cached result (no duplicate generation)
  • Same key + different body → IDEMPOTENCY_KEY_REUSE (409)
  • Key still processing → REQUEST_IN_PROGRESS (409)

Rate Limiting

Two buckets: read (higher limits — queries, lists) and generate (lower limits — mutations, generation). Per-account enforcement. Exceeding returns an error message at tool level; HTTP 429 at transport level.

Permissions

| Permission | Tools | |-----------|-------| | voices:list | search_voices | | tts:generate | generate_speech | | tts:status | get_job_status, get_audio_link | | jobs:read | list_jobs, get_job_text | | jobs:write | delete_job_audio, update_job_metadata | | shares:read | list_shares, get_share, list_access_codes, export_access_codes | | shares:write | create_share, update_share, revoke_share, bulk_revoke_shares, toggle_share_permanent, update_track_order, create_access_codes, update_access_code, delete_access_code, get_qr_code | | library:read | list_collections, list_tags, list_bookmarks | | library:write | manage_collection, create_bookmark, delete_bookmark, manage_bookmark_collection | | storage:read | get_storage, list_storage_items | | storage:write | bulk_delete_storage | | pricing:estimate | estimate_cost | | usage:read | get_usage |

Error Reference

| Code | Status | Description | |------|--------|-------------| | VALIDATION_ERROR | 400 | Invalid input parameters | | INVALID_VOICE | 400 | Voice ID not found or invalid | | PROVIDER_DISABLED | 400 | Provider unknown or disabled | | INSUFFICIENT_CREDITS | 402 | Not enough credits | | STORAGE_CAP_EXCEEDED | 403 | Storage quota full | | FORBIDDEN | 403 | Enterprise-only or ownership failed | | INVALID_WEBHOOK_URL | 400 | Webhook URL validation failed | | ENTERPRISE_TIER_REQUIRED | 400 | Enterprise pricing without tier | | STREAM_NOT_SUPPORTED | 400 | Voice/provider doesn't support streaming | | SPEED_OUT_OF_RANGE | 400 | Speaking rate exceeds stream limit | | STREAM_BITRATE_NOT_SUPPORTED | 400 | Bitrate in stream mode | | STREAM_FORMAT_MISMATCH | 400 | Format not supported for stream | | MAINTENANCE | 503 | API in maintenance mode | | IDEMPOTENCY_KEY_REUSE | 409 | Key reused with different body | | REQUEST_IN_PROGRESS | 409 | Key still processing | | JOB_NOT_FOUND | 404 | Job doesn't exist or not owned | | JOB_IN_PROGRESS | 409 | Cannot delete pending/processing job | | TEXT_UNAVAILABLE | 410 | Job expired or text not stored | | SHARE_NOT_FOUND | 404 | Share doesn't exist or not owned | | AMBIGUOUS_SHARE_INPUT | 400 | Both job_ids and source provided | | INVALID_SHARE_SOURCE | 400 | Invalid source configuration | | PASSWORD_REQUIRED | 400 | auth_mode=password without password | | INVALID_AUTH_MODE_PASSWORD_COMBO | 400 | auth_mode and password combination invalid | | SOURCE_IMMUTABLE | 400 | Cannot change source on source-backed share | | ACCESS_CODE_NOT_FOUND | 404 | Access code doesn't exist | | COLLECTION_NOT_FOUND | 404 | Collection doesn't exist or not owned | | BOOKMARK_NOT_FOUND | 404 | Bookmark or collection doesn't exist | | ALREADY_EXISTS | 409 | Bookmark already exists |

Error envelope: { error: "message", code?: "ERROR_CODE", status?: 404 }

Configuration

| Variable | Required | Description | |----------|----------|-------------| | AITTSM_API_KEY | Yes | API key (starts with tts_) | | AITTSM_BASE_URL | No | Custom API base URL |

Requirements

Links

License

MIT