{"id":"effect-subscribe-cta","kind":"effect","name":{"he":"כפתור עקבו","en":"Follow button click"},"one_line":{"he":"כפתור עקבו קופץ, סמן מחליק אליו ולוחץ: הוא הופך ל״במעקב ✓״ ופעמון מצלצל.","en":"A follow button pops in, a cursor glides over and clicks it: it turns to “following ✓” and a bell rings."},"listed":true,"version":"1.0","updated":"2026-10-09","when_to_use":["A overlays & graphics effect at a chosen moment: A follow button pops in, a cursor glides over and clicks it: it turns to “following ✓” and a bell rings.","On its own (one call), or added to captions and a hook in the same render (its entry in `effects`)."],"when_not_to_use":["The customer wants a finished video from raw footage: a complete video does the planning (the full tab of /skills)."],"example":null,"preview":{"clip_url":"https://media.gpt.org.il/lookbook/effects/subscribe-cta.mp4?v=mv19exzc","poster_url":"https://media.gpt.org.il/lookbook/effects/subscribe-cta.jpg?v=mv19exzc"},"price":{"unit":"minute","from":60,"to":60,"note":"per finished minute: the render itself; nothing extra when it joins captions and a hook"},"inputs":[{"name":"video_url","type":"video","required":true,"limits":"a public link, or the original recording uploaded (POST /v1/studio/uploads), up to 2 GB","notes":"upload the original as it is (a phone's MOV / HEVC / 4K is fine), never a resized copy"},{"name":"params · start · duration","type":"json","required":false,"limits":"every param has a default and a range (the recipe lists them)","notes":"start / duration are seconds of the finished video, or anchored to words with at / during"}],"outputs":[{"name":"output.url","type":"video","required":true,"limits":"mp4, 9:16 1080p unless the request says otherwise","notes":"the file is deleted 24 hours after it is made: download it and tell the customer"},{"name":"cost","type":"number","required":true,"limits":null,"notes":"GET /v1/usage?tag=<job name> → totals.credits: quote this, not the estimate"}],"steps":[{"method":"POST","path":"/v1/studio/uploads","what":"Only for a file (not a link): get an upload URL, PUT the bytes to output.upload_url with output.headers, use output.url as the video","body":{"filename":"clip.mp4"},"async":false,"optional":true},{"method":"POST","path":"/v1/effects/subscribe-cta/estimate","what":"The price (the same body)","body":{"video_url":"<the video>","start":0.2,"duration":3.6},"async":false,"optional":false},{"method":"POST","path":"/v1/effects/subscribe-cta","what":"The effect on the video, one render — or put its entry in `effects` of POST /v1/studio/edit with captions and a hook","body":{"video_url":"<the video>","start":0.2,"duration":3.6},"async":true,"optional":false},{"method":"GET","path":"/v1/executions/{id}","what":"Poll a call that answered processing until it is completed (the file is output.url)","body":null,"async":false,"optional":false},{"method":"GET","path":"/v1/usage","what":"?tag=<job name>: what the whole job cost — quote it to the customer","body":null,"async":false,"optional":false}],"rules":["Show the customer the price (POST <path>/estimate with the same body, or the price above) and wait for their OK before any paid call.","Send Idempotency-Key: <job>-<step> on every POST. After a timeout send the same call with the SAME key — you get the same job back, never a second charge.","A long call answers status processing: poll GET /v1/executions/{id} every 5–10 s (or send x-wait-ms, up to 90000). Never send the job again to see whether it finished.","Send the same X-Tag: <job name> on every call of one job; GET /v1/usage?tag=<job name> is then what it really cost.","A caption style, a hook and effects are ONE job: put them in the same POST /v1/studio/edit (one render, the price of captions alone). Never render twice, and never caption a video that already has burned-in captions."],"common_errors":[{"code":"invalid_input","why":"400: a field is missing, misspelled or out of range — the message names it","fix":"Fix exactly that field and send again; send only the fields the recipe or the docs show."},{"code":"unauthorized","why":"401: the API key is missing, wrong or revoked","fix":"Ask the customer for a valid key (keys are made at /api-keys); never print it back."},{"code":"insufficient_credits","why":"402: the balance does not cover the estimate (details.required_credits)","fix":"Tell the customer the price and that the balance is short; do not retry until they top up."},{"code":"rate_limited","why":"429: too many calls a minute","fix":"Wait the retry-after seconds, then send the same call with the same Idempotency-Key."},{"code":"failed","why":"the execution's status is failed or timeout — nothing is charged for failed work","fix":"Read error.message, fix the input, and start again with a NEW Idempotency-Key."},{"code":"upload_too_large","why":"413: the file is bigger than the call takes","fix":"Upload the original through POST /v1/studio/uploads and send its output.url; never shrink the picture's shape."}],"quality_check":["The effect plays at the moment the words call for, and nothing it draws leaves the frame.","Watch the start, the middle and the end of the result before handing it over — not only its status.","Read `warnings` in the answer (a font swapped for the language, a picture that had to be enlarged) and tell the customer what they mean."],"tags":{"domain":"edit","level":"basic","hebrew":false,"recommended":false,"new":false,"creator":false,"topics":["effect","overlay"]},"links":{"recipe":"/skills/effect-subscribe-cta.md","docs":"/docs?tool=video-effects","run":null}}