writer-instagram
Instagram caption FORMAT rules — length, hook, hashtags, emoji, the link limitation and image aspect. Read this ONLY when you are writing an Instagram post inside a task — `task-content-publish`'s `compose` node or `task-calendar-plan`'s `generate` node. It has no entry of its own and must never be entered directly.
name: writer-instagram
description: Instagram caption FORMAT rules — length, hook, hashtags, emoji, the link limitation and image aspect. Read this ONLY when you are writing an Instagram post inside a task — task-content-publish's compose node or task-calendar-plan's generate node. It has no entry of its own and must never be entered directly.
tags: [internal, marketing]
license: MIT-0
Instagram copy rules
Governs FORMAT only — how an Instagram post is shaped. What the brand sounds like
comes from Brand IQ; product truth (only what the product tools returned) and the
anti-AI-slop check (humanizer) belong to the task you are writing in — compose in
task-content-publish or generate in task-calendar-plan. Apply this on top of both;
you never need to read the other task to apply it.
Spec
| field | rule |
|---|---|
| length | 80–2200 characters, sweet spot 125–600. 2200 is Instagram's HARD cap and it counts EVERY character: spaces, line breaks, punctuation, emoji and the whole trailing hashtag block all spend the same budget — so count the finished caption WITH its hashtags, not the prose alone. Over the cap Instagram rejects the post outright; it does not trim it for you |
| hook | first 125 chars must stand alone (they show before "… more") — lead with the payoff, not a windup. The payoff is concrete: a feature or use the product truth actually states, or the attached campaign's offer — never a line about choosing, exploring, or what "feels right", which says nothing about this product. Before you submit, count three things: that concrete opening, at least one more concrete selling point after it, and a closing call to action that names the product (or the code, when a campaign is attached) — except when the merchant asked for a piece that does not sell: then no call to action |
| hashtags | Exactly the ones the merchant picked — you choose none of them. Print that set and no more — with ONE carve-out: a pre-filled default the merchant never typed that the products cannot honestly carry stays on the card and OUT of the caption (the task you are writing in owns that call); a tag they typed themselves always prints. Do not add, top up to a nicer count, infer one from the copy, the products or the season, or borrow one from another channel's row — a blog's SEO term is not a hashtag. Grouped in a trailing block on their own line, never sprinkled inline; each starts with a literal # (e.g. #snowboard) — NEVER % or any other character. No picks means no hashtag block at all, which is a valid caption |
| emoji | ≤5, purposeful; not as bullet decoration |
| formatting | plain text ONLY, and the finished caption contains NOT ONE asterisk (*) — Instagram renders no markdown, so any markup publishes as literal characters in front of the merchant's followers (ruled 2026-10-22: zero * in the caption, full stop). # belongs to hashtags alone, never headings. Emphasis comes from word choice, line breaks and the allowed emoji, never from markup. Before the draft call, scan the caption: an asterisk anywhere means rewrite that line |
| discount code | When the piece carries a campaign, print THIS channel's variant code — {CODE}-IG, from the campaign's variant_codes map — never the campaign's main code. An Instagram caption has no link, so the redeemed code is the ONLY thing that tells this post's sales from every other post's; printing the main code files this post's revenue under the campaign as a whole and the piece is measured as zero. One code per caption, written out in capitals so it can be typed from a phone Only ever print a code that came from a tool or the card — the campaign object names the codes that exist in Shopify. Never compose one, never adapt one you have seen, and if the piece carries no campaign then it carries no code: a code that does not exist is refused at checkout for every shopper who types it, and the draft tool refuses the piece rather than publishing it (measured on dev 2026-08-28 — an Instagram post advertised WINTERSALE10 on a store that has never had that code). Urgency is only ever the campaign's own. Say the offer ends on a date only when the campaign carries one — ends_at, or the end of the card's "Runs: X to Y" line — and quote that date as given — never a count of days left; a campaign with no end date gets no "limited time", "last chance", "ends soon" or "while it lasts"; and never say stock is running out. A deadline that is not real is a lie to the shopper, and a code that never expires next to "last chance" is exactly that. |
| links | NO link of any kind in an Instagram caption, and the phrase "link in bio" is BANNED (2026-08-28) — the bio link is not ours to manage and the line reads as filler. The caption sells by naming the product; conversions ride the discount code. Never paste a URL and never imply the caption is clickable |
| image | required; JPEG, square 1024×1024 or 4:5 portrait (NOT taller like 2:3 — Instagram crops it). Keep files ≤8MB |
Image
An Instagram post is image-first — it ALWAYS ships with a visual, and the copy is
written assuming the reader already sees it. The picture is not yours to make here:
the server draws it WITH the draft, from the hero_scene you pass to
CREATE_CONTENT_DRAFT, and attaches it to the card (the result answers
hero_image: "drawn"; illustrate only ever CHANGES a picture that already exists).
Do not call GENERATE_IMAGE from this skill, and do not
describe a specific picture in the copy as if you had seen it — write for the scene the
piece is about. What this skill governs is the shape the picture has to fit: square 1024×1024 or 4:5 portrait, JPEG, ≤8MB.
No [[IMAGE: …]] markers here. Those belong to a blog article's body only. This
post carries exactly one picture, the piece's hero, and it is attached to the card
rather than written into the copy — a marker in a caption is stripped and draws
nothing.
Voice & structure
- The caption extends the image, it doesn't restate it — assume the reader already sees the photo.
- Relaxed and human but with a point of view: one idea per post, one CTA.
- Short lines / line breaks over dense paragraphs; must scan on a phone.
- Do: open on the payoff, benefit, or a concrete detail; end with one soft CTA.
- Don't: long-form multi-paragraph essays; fake intimacy ("Hey friends!!"); press-release voice ("We are thrilled to announce"); walls of inline hashtags.
- Price appears ONLY when it is the message — an attached campaign's discount anchor, or the merchant's brief names affordability as the selling point. Otherwise leave it out: the product page the CTA points to owns the price, and published copy cannot be re-priced — a stale number becomes misinformation with the merchant's name on it. Never "DM for price".
These rules are constraints on you, not a bulletin for the merchant
Everything above shapes what you write. None of it is something to read out. Measured on 2026-08-21: the caption-cannot-hold-a-clickable-link rule was relayed to the merchant as a "Note:" paragraph in the chat, alongside a restatement of the whole draft — the merchant did not ask how the channel works and the draft card already showed the result. Apply the rule silently: the card shows what they are getting, and the turn a draft lands carries no text of yours.
Download
ZIP package — ready to use
Skill Info
- Creator
- Yepai
- License
- MIT-0
- Downloads
- 0
- Published
- Oct 26, 2026
- Updated
- Oct 29, 2026