[{"slug":"ZV-2026-1510","server_name":"api.weftly.ai","severity":"breaking","title":"api.weftly.ai: Tool publish_to_youtube was removed.","summary":"[breaking] Tool publish_to_youtube was removed.","changes":[{"kind":"tool_removed","tool":"publish_to_youtube","detail":"Tool `publish_to_youtube` was removed.","severity":"breaking"}],"published_at":"2026-09-27T22:49:16.440Z"},{"slug":"ZV-2026-1476","server_name":"api.weftly.ai","severity":"breaking","title":"api.weftly.ai: Tool clips_horizontal was removed.","summary":"[breaking] Tool clips_horizontal was removed. [breaking] Tool clips_vertical was removed. [breaking] Tool extract_clip was removed. [breaking] Tool extract_vertical_clip was removed. [breaking] Tool get_youtube_publish_status was removed. [breaking] Tool trigger_youtube_publish was removed. [safe] Tool clips_from_job was added. [safe] Tool clips_from_video was added. [safe] Tool edit_from_transcript was added. [safe] Description of find_clips changed (7% word delta). [safe] Description of get_job_status changed (24% word delta). [risky] Enum value edit added to format on get_job_status. [risky] Description of publish_to_youtube changed (25% word delta). [safe] Description of summarize changed (5% word delta). [safe] Description of transcribe changed (6% word delta).","changes":[{"kind":"tool_removed","tool":"clips_horizontal","detail":"Tool `clips_horizontal` was removed.","severity":"breaking"},{"kind":"tool_removed","tool":"clips_vertical","detail":"Tool `clips_vertical` was removed.","severity":"breaking"},{"kind":"tool_removed","tool":"extract_clip","detail":"Tool `extract_clip` was removed.","severity":"breaking"},{"kind":"tool_removed","tool":"extract_vertical_clip","detail":"Tool `extract_vertical_clip` was removed.","severity":"breaking"},{"kind":"tool_removed","tool":"get_youtube_publish_status","detail":"Tool `get_youtube_publish_status` was removed.","severity":"breaking"},{"kind":"tool_removed","tool":"trigger_youtube_publish","detail":"Tool `trigger_youtube_publish` was removed.","severity":"breaking"},{"kind":"tool_added","tool":"clips_from_job","detail":"Tool `clips_from_job` was added.","severity":"safe"},{"kind":"tool_added","tool":"clips_from_video","detail":"Tool `clips_from_video` was added.","severity":"safe"},{"kind":"tool_added","tool":"edit_from_transcript","detail":"Tool `edit_from_transcript` was added.","severity":"safe"},{"kind":"description_changed","tool":"find_clips","after":"START HERE for any clip workflow on a video — `find_clips` is the canonical entry point and includes a full transcription as a free byproduct. **Do not call `transcribe` first**: doing so doubles the upload, doubles the spend, and produces the same transcript. Identify ranked candidate clips in a video — what to cut for highlights, social, or testimonials. Three-call flow: (1) call with `filename` (and optional `query`) to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns three outputs: role `clip-candidates` (JSON matching /.well-known/weftly-clips-v1.schema.json — includes `source_job_id` and `source_expires_at`), role `transcript` (SRT, free byproduct), role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, free byproduct). Each candidate carries `transcript_text` — the full text of what's in the clip — so callers can preview content before paying for clips_from_job. Optional `query` parameter switches to query mode (e.g., \"they discuss pricing\", \"the part about hiring\") with the same output shape; the `mode` field in clip-candidates.json indicates which mode produced the result. Flat price: $2.00 video — see /.well-known/mpp.json. **Source-reuse contract:** the source video stays in storage for 72h after find_clips completes. Hand the find_clips `job_id` (also returned as `source_job_id` in the candidates JSON) to `clips_from_job` as its `source_job_id` — within those 72h it cuts directly from the stored source: no re-upload, no re-transcribe, just $0.50 per cut (more for a multi-clip `output: \"files\"` batch). Pass the same `source_job_id` to as many `clips_from_job` calls as you need. Use for interviews, podcasts, sales calls, all-hands recordings. Retrying with `job_id` alone returns current state. Failed jobs auto-refund.","before":"START HERE for any clip workflow on a video — `find_clips` is the canonical entry point and includes a full transcription as a free byproduct. **Do not call `transcribe` first**: doing so doubles the upload, doubles the spend, and produces the same transcript. Identify ranked candidate clips in a video — what to cut for highlights, social, or testimonials. Three-call flow: (1) call with `filename` (and optional `query`) to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns three outputs: role `clip-candidates` (JSON matching /.well-known/weftly-clips-v1.schema.json — includes `source_job_id` and `source_expires_at`), role `transcript` (SRT, free byproduct), role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, free byproduct). Each candidate carries `transcript_text` — the full text of what's in the clip — so callers can preview content before paying for extract_clip. Optional `query` parameter switches to query mode (e.g., \"they discuss pricing\", \"the part about hiring\") with the same output shape; the `mode` field in clip-candidates.json indicates which mode produced the result. Flat price: $2.00 video — see /.well-known/mpp.json. **Source-reuse contract:** the source video stays in storage for 72h after find_clips completes. Hand the find_clips `job_id` (also returned as `source_job_id` in the candidates JSON) to `extract_clip` or `extract_vertical_clip` as their `source_job_id` — within those 72h they cut directly from the stored source: no re-upload, no re-transcribe, just $0.50 per cut. Pass the same `source_job_id` to as many extract calls as you need. Use for interviews, podcasts, sales calls, all-hands recordings. Retrying with `job_id` alone returns current state. Failed jobs auto-refund.","detail":"Description of `find_clips` changed (7% word delta).","severity":"safe","descriptionDelta":0.0674157303370787},{"kind":"description_changed","tool":"get_job_status","after":"Check the status of a transcribe or summarize job. Returns the current state and, when completed, an `outputs` array. Each output has either `content` (returned inline) or a presigned, time-limited (1 hour) `download_url`. Small text outputs (e.g. `transcript` SRT, `clip-candidates`, `summary`) come inline as `content`; larger outputs — `transcript-words` JSON for any non-trivial recording, plus video outputs like `clip-video` / `clip-vertical-video` — come as a `download_url` to fetch when needed. Optionally pass `format` (srt, txt, vtt, json, words, edit) to get the transcript content inline in the top-level `transcript` field — `txt` and `vtt` are derived from the stored SRT; `json` is v1 (segments only); `words` is v2 (segments + per-word timestamps matching /.well-known/weftly-transcript-v2.schema.json); `edit` is a plain-text \"[NNNN] words...\" paragraph list, one line per paragraph, for editing by hand — send the edited text to edit_from_transcript to cut a re-timed video from it. Poll this periodically after calling complete_upload — wait at least 60 seconds between checks. For files under 10 minutes, jobs usually complete within 1-2 minutes. For long files (1hr+), expect 10-30 minutes. Derivative jobs (`extract_clip`, `extract_vertical_clip`, `publish_youtube`, `clips_vertical`, `clips_horizontal`, `edit_from_transcript`) have no upload step and no `awaiting_upload`/`awaiting_complete_upload` states — a paid derivative job reports `processing` once its parent source is confirmed still in storage, or a terminal `source_expired` if the parent source has expired: stop polling, and re-run the parent job named in `source_job_id` to get a fresh source before retrying. `publish_youtube` is the one exception: its upload starts by itself as soon as payment settles, so a paid job goes straight to `publishing`. If it reports `awaiting_trigger` instead, the upload did not start — almost always because the YouTube account is not connected yet; connect it and the publish can be resumed. A completed `publish_youtube` job's `outputs` array carries a `youtube_url`-roled entry with a `url` field pointing straight at the published video, instead of a `download_url`.\n\nAlso use this to recover from lost state: if the original challenge was lost, call get_job_status(job_id) to retrieve a fresh challenge (status \"awaiting_payment\") or the upload URL (status \"awaiting_upload\").","before":"Check the status of a transcribe or summarize job. Returns the current state and, when completed, an `outputs` array. Each output has either `content` (returned inline) or a presigned, time-limited (1 hour) `download_url`. Small text outputs (e.g. `transcript` SRT, `clip-candidates`, `summary`) come inline as `content`; larger outputs — `transcript-words` JSON for any non-trivial recording, plus video outputs like `clip-video` / `clip-vertical-video` — come as a `download_url` to fetch when needed. Optionally pass `format` (srt, txt, vtt, json, words) to get the transcript content inline in the top-level `transcript` field — `txt` and `vtt` are derived from the stored SRT; `json` is v1 (segments only); `words` is v2 (segments + per-word timestamps matching /.well-known/weftly-transcript-v2.schema.json). Poll this periodically after calling complete_upload — wait at least 60 seconds between checks. For files under 10 minutes, jobs usually complete within 1-2 minutes. For long files (1hr+), expect 10-30 minutes. Derivative jobs (`extract_clip`, `extract_vertical_clip`, `publish_youtube`, `clips_vertical`, `clips_horizontal`) have no upload step and no `awaiting_upload`/`awaiting_complete_upload` states — a paid derivative job reports `processing` once its parent source is confirmed still in storage, or a terminal `source_expired` if the parent source has expired: stop polling, and re-run the parent job named in `source_job_id` to get a fresh source before retrying.\n\nAlso use this to recover from lost state: if the original challenge was lost, call get_job_status(job_id) to retrieve a fresh challenge (status \"awaiting_payment\") or the upload URL (status \"awaiting_upload\").","detail":"Description of `get_job_status` changed (24% word delta).","severity":"safe","descriptionDelta":0.24285714285714288},{"kind":"enum_value_added","path":"inputSchema.properties.format","tool":"get_job_status","after":"edit","detail":"Enum value `edit` added to `format` on `get_job_status`.","severity":"risky"},{"kind":"description_changed","tool":"publish_to_youtube","after":"Publish an existing video from a transcribe or summarize job to YouTube. Creates a paid publish job (flat $1.75 price) and stores the OAuth token. Captions are auto-generated from the session transcript if available. Workflow: create_job → pay → poll get_job_status. The upload starts by itself once payment settles — there is no separate trigger step. Requires a YouTube OAuth2 access token obtained independently via Google OAuth (scope: youtube.upload).","before":"Publish an existing video from a transcribe or summarize job to YouTube. Creates a paid publish job (flat $1.75 price) and stores the OAuth token. Captions are auto-generated from the session transcript if available. Workflow: create_job → pay → trigger_youtube_publish → poll get_youtube_publish_status. Requires a YouTube OAuth2 access token obtained independently via Google OAuth (scope: youtube.upload).","detail":"Description of `publish_to_youtube` changed (25% word delta).","severity":"risky","descriptionDelta":0.2542372881355932},{"kind":"description_changed","tool":"summarize","after":"Summarize an audio or video file — returns both a text summary AND the full transcript (with per-word timestamps). Do not also call transcribe on the same file. Three-call flow: (1) call with `filename` to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns three outputs: role `summary` (plain text), role `transcript` (SRT), and role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, with segment-level and per-word timestamps). For other formats, pass `format=srt|txt|vtt|json|words|edit` to get_job_status to receive transcript content inline — `txt` and `vtt` are derived from SRT, `json` is v1 (segments only), `words` is v2 (segments + words), `edit` is a plain-text \"[NNNN] words...\" paragraph list for editing by hand. Flat price: audio $0.75, video $1.25 — see /.well-known/mpp.json for the authoritative table. Use for meetings, long-form interviews, lectures, and podcast episodes; the `words` output additionally supports creating clips, multicamera edits, or edit-video-from-transcript. Retrying any call with `job_id` alone returns current state (idempotent). Failed jobs auto-refund.","before":"Summarize an audio or video file — returns both a text summary AND the full transcript (with per-word timestamps). Do not also call transcribe on the same file. Three-call flow: (1) call with `filename` to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns three outputs: role `summary` (plain text), role `transcript` (SRT), and role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, with segment-level and per-word timestamps). For other formats, pass `format=srt|txt|vtt|json|words` to get_job_status to receive transcript content inline — `txt` and `vtt` are derived from SRT, `json` is v1 (segments only), `words` is v2 (segments + words). Flat price: audio $0.75, video $1.25 — see /.well-known/mpp.json for the authoritative table. Use for meetings, long-form interviews, lectures, and podcast episodes; the `words` output additionally supports creating clips, multicamera edits, or edit-video-from-transcript. Retrying any call with `job_id` alone returns current state (idempotent). Failed jobs auto-refund.","detail":"Description of `summarize` changed (5% word delta).","severity":"safe","descriptionDelta":0.04958677685950408},{"kind":"description_changed","tool":"transcribe","after":"Transcribe audio or video to text, including per-word timestamps for precise editing. Three-call flow: (1) call with `filename` to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns two outputs: role `transcript` (SRT) and role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, with segment-level and per-word timestamps). For other formats, pass `format=srt|txt|vtt|json|words|edit` to get_job_status to receive content inline — `txt` and `vtt` are derived from SRT, `json` is v1 (segments only), `words` is v2 (segments + words), `edit` is a plain-text \"[NNNN] words...\" paragraph list for editing by hand. Flat price: audio $0.50, video $1.00 — see /.well-known/mpp.json for the authoritative table. Use for podcasts, interviews, meetings, lectures, and especially for creating clips, multicamera edits, or edit-video-from-transcript where word boundaries matter. Retrying any call with `job_id` alone returns current state (idempotent). Failed jobs auto-refund.","before":"Transcribe audio or video to text, including per-word timestamps for precise editing. Three-call flow: (1) call with `filename` to receive {job_id, payment_challenge}; (2) pay via MPP, then call with `job_id` + `payment_credential` to receive {upload_url} (presigned PUT, 1h expiry); (3) PUT the bytes, then complete_upload(job_id), then poll get_job_status(job_id). On completion, get_job_status returns two outputs: role `transcript` (SRT) and role `transcript-words` (JSON matching /.well-known/weftly-transcript-v2.schema.json, with segment-level and per-word timestamps). For other formats, pass `format=srt|txt|vtt|json|words` to get_job_status to receive content inline — `txt` and `vtt` are derived from SRT, `json` is v1 (segments only), `words` is v2 (segments + words). Flat price: audio $0.50, video $1.00 — see /.well-known/mpp.json for the authoritative table. Use for podcasts, interviews, meetings, lectures, and especially for creating clips, multicamera edits, or edit-video-from-transcript where word boundaries matter. Retrying any call with `job_id` alone returns current state (idempotent). Failed jobs auto-refund.","detail":"Description of `transcribe` changed (6% word delta).","severity":"safe","descriptionDelta":0.0625}],"published_at":"2026-09-26T18:05:13.926Z"}]