# FishAudio private Coze plugin import package

This directory is for customers who prefer to create private plugins in their own Coze workspace instead of installing the public store listings.

## Files

- `fishaudio-tts.openapi.yaml`: one `generate_tts` text-to-speech tool.
- `fishaudio-media-sync.openapi.yaml`: `create_media_sync` and `get_media_sync_job`.
- `fishaudio-video-dubbing.openapi.yaml`: `create_text_lip_sync` and `get_text_lip_sync_job` for text-to-lip-sync video generation.
- `fishaudio-personal-voice.openapi.yaml`: customer-specific private plugin for personal voice synthesis; not a store candidate.
- `fishaudio-tts-icon.png`: FishAudio avatar with a `TTS` badge.
- `fishaudio-media-sync-icon.png`: FishAudio avatar with an `LS` badge for image/video lip sync.
- `fishaudio-video-dubbing-icon.png`: Text-to-lip-sync avatar with a `VD` badge.
- `fishaudio-personal-voice-icon.png`: Customer-specific private plugin avatar with a `PVS` badge.
- `manifest.json`: package version, endpoint, and file inventory.

The three store candidates are independent: import TTS to generate audio with an existing voice, Media Sync to create lip-synced video from existing audio, or Video Dubbing to generate speech from text and create the lip-synced video in one request. Personal Voice Synthesis remains a customer-specific private plugin and is not a store candidate.

## Import into Coze

1. Open the resource library and create a plugin.
2. Select a cloud plugin.
3. Select the option to create from an existing service.
4. Use Import to upload or paste the relevant OpenAPI YAML file.
5. Confirm that the plugin URL is `https://fishaudio.org`.
6. Select no authorization. Each customer supplies `Authorization` as a tool input at runtime.
7. Enable the imported tools and run them with the customer's own Fish Audio API key.
8. Publish to the customer's workspace. Private use does not require plugin-store review.

## Authorization

Every tool expects:

```text
Bearer YOUR_FISH_AUDIO_API_KEY
```

There must be one space after `Bearer`. Never put a real key in the YAML, a screenshot, or a shared workflow template. Create a separate Coze key and rotate or revoke it when needed.

## TTS requirements

The TTS file calls:

```text
POST https://fishaudio.org/api/open/v1/speech/tts
```

Keep `cache` set to `true`. This makes the API return JSON containing `audio_url`. Setting it to `false` returns raw audio bytes, which Coze may reject as an unparseable response.

The `audio_url` is temporary and currently expires after three days. Download or transfer it promptly.

## Media Sync requirements

Save `data.id` from the create tool and pass it to the query tool as `jobId`:

```text
create_media_sync → data.id → wait 15–30 seconds → get_media_sync_job
```

- `processing`: query the same `jobId` again.
- `completed`: read `data.result_url`.
- `failed`: read `data.error_message`.

Do not call `create_media_sync` again when a query times out or the job remains processing. That can create and charge for a duplicate job.

Video and audio URLs must be directly downloadable by the Fish Audio service. Web pages, local paths, and expired signed URLs cannot be used as media inputs.

Video mode bills the shorter video/audio input, rounded up to a whole second. The create response returns `billing_duration_seconds` and `credits_used`; successful-job pricing does not change later, while failed jobs receive a full refund. Set `video_extension: true` only when the video must be extended to the audio duration.

## Text-to-lip-sync requirements

This plugin uses the same combined API as the website Video Dubbing workbench. The service generates TTS audio with the selected voice and then creates the lip-sync job automatically:

```text
create_text_lip_sync → data.id → wait 15–30 seconds → get_text_lip_sync_job
```

- Provide `video_url`, target `text`, and an existing voice `reference_id`; no pre-generated `audio_url` is required.
- Use a new `Idempotency-Key` for every new job. Reuse the original value only when retrying the exact same request.
- `data.audio_url` in the create response is the intermediate TTS audio; read the final video from `data.result_url` in the query response.
- `credits_used` separates `tts`, `lip_sync`, and `total`.
- Querying the same `jobId` does not regenerate speech or charge again. Never recreate a job while it is processing.

## Customer-specific Personal Voice Synthesis requirements

This plugin combines persistent private-voice creation with asynchronous TTS:

```text
create_personal_voice → data.id → wait → get_personal_voice_job
```

- Provide `source_audio_url` and the target `text`; a reference transcript is not required.
- The source URL must be directly downloadable by Fish Audio and is limited to 10 MB.
- Use a new `Idempotency-Key` for every new job. Reuse the original value only when retrying the exact same request.
- A successful create response contains the persistent `data.voice_id`, which can be reused with ordinary TTS.
- When the job is `completed`, read `data.audio_url`; the temporary URL currently expires after three days.
- Voice cloning and TTS are charged separately. If cloning succeeds but TTS startup fails, the error contains `clone_completed: true` and `voice_id`; the created voice and clone charge remain.

## Pre-publish checklist

- The import creates one TTS tool, two Media Sync tools, two Text-to-Lip-Sync tools, or two customer-specific Personal Voice Synthesis tools as applicable.
- A TTS test returns a non-empty `audio_url`.
- A create test returns a non-empty `data.id`.
- The query tool exposes `status`, `progress`, `result_url`, and `error_message`.
- Text-to-Lip-Sync returns `data.id` and `data.audio_url`, then exposes `data.result_url` when complete.
- Customer-specific Personal Voice Synthesis returns `voice_id` and `data.id`, then exposes `audio_url` when complete.
- No real API key is stored in the plugin or a saved example.
