VibeDayAI-Powered Social Media Management

Generations

From draft to approval: review captions, regenerate the image, iterate on locked fields, then push READY so the scheduler can pick it up.

A generation is one AI-produced post — captions, hashtags, CTA, image prompt — drafted from a topic. Generations are first drafts; you review, edit, and approve them before they're eligible for scheduling.

What's in a generation

A generation in VibeDay holds:

  • Name — a short, descriptive title (e.g. "Golden-hour beach sunset"). The AI drafts it as part of the same step that writes your captions, so every AI post gets a recognizable name instead of a generic label. Uploaded content is named from its filename. You can rename it any time (see below).
  • Captions for three platforms — Instagram, Facebook, TikTok — each in that platform's idiomatic style
  • YouTube title + description (optional) — the AI also drafts a punchy YouTube headline (≤100 chars) and a longer description (≤5000 chars). Editable in the editor and used when the post is published to YouTube. Optional at approve — you're never blocked from approving just because you don't post to YouTube.
  • Hashtags — 3–15, no # prefix, drafted in CamelCase (#SmallBusinessTips). Capitals are kept as written (operator 2026-10-13); two tags that differ only in case count as one, and the first spelling wins. Tags saved before 2026-10-13 stay lowercase. Drafted hashtags are spell-checked before you see them: a tag that is one letter off your brand name or a phrase from your request or the drafted caption (e.g. #HouseBend when the caption says "house blend") is corrected to that spelling — the brand's own spelling, or the caption's words in CamelCase (#HouseBlend). Tags that are not near anything you wrote are left as the AI wrote them.
  • Call to action (optional) — one line; AI only writes one when natural for the topic
  • Image — a 1024×1024 AI-illustrated PNG (via OpenAI gpt-image-2). The image prompt is also stored so you can see what the AI illustrated from.
  • Trace — which model/provider produced it, the prompt used, credit cost, iteration number
  • Status — DRAFT / READY / FAILED / ARCHIVED (see below)

Status lifecycle

DRAFT → READY                    (you approve it)
      → ARCHIVED                 (you discard it)
[any] → FAILED                   (generation hit an error)
  • DRAFT — just generated, awaiting your review
  • READY — approved by you; eligible for scheduling (Sprint 4+)
  • FAILED — the AI call or save failed; the row exists but has no usable content
  • ARCHIVED — discarded; not visible in default views

New generations always land in DRAFT. You explicitly promote to READY by clicking Approve for posting — there's no auto-approval. This is intentional: AI output is a starting point, not the final word.

Generating a post

From the Topics list, click the green Generate draft button on a topic row. A blocking modal appears with:

  • A circular progress arc filling toward the expected duration (~15 seconds)
  • An elapsed counter ("12s")
  • Adaptive copy that flips to "Taking a little longer than usual — still working…" if it goes over

When the AI finishes you're redirected to /generations/[id] — the detail view of your new draft.

If the AI errors, the modal switches to a red error state with the underlying detail and a Dismiss button. The modal stays open until you dismiss it so you can read the message in full.

The generation detail page

The detail page (/generations/[id]) shows:

  • Header — the generation's name with a small pencil button to rename it inline (click the pencil → edit → Save / Cancel; Enter saves, Esc cancels), a DRAFT badge (yellow) or READY badge (green), and a meta line beneath: {date} · {type} · {source} · #{seq} (e.g. "Jun 18 · Image · AI Studio · #014"). Source campaign + brand links and the source-topic link follow.
  • Amber callout (DRAFT only) — "This is a draft. Review and edit if needed, then click Approve for posting…"
  • Platform caption row — Instagram, Facebook, TikTok, and YouTube captions in one horizontally-scrollable row of cards; scroll left/right to work on each (new platforms drop into the same row). Every field has a ? hover-note explaining what it is and how to use it
  • Hashtags card — chips of every hashtag
  • CTA card — the call to action, or "No CTA — the AI judged the topic didn't need one"
  • Image card — the AI-generated illustration (1024×1024). On DRAFT, a Regenerate image button lets you try a different illustration without rewriting the captions. The prompt is collapsed under "Show the prompt & settings" (see The prompt panel).
  • Footer trace — model used, credit cost, iteration number

Header actions:

  • Regenerate — drafts a new variant from the same topic (always available)

When the status is DRAFT, the captions / hashtags / CTA are editable inline. Below the editable cards is an action bar with:

  • Approve for posting (green) — promote the draft to READY without saving any edits. Becomes Save & approve the moment you change anything.
  • Save changes (only visible when you have unsaved edits) — persist edits without changing status; stays DRAFT.
  • Discard changes (only visible when you have unsaved edits) — revert to the last saved version.

When the status is READY (or FAILED / ARCHIVED), the captions / hashtags / CTA render read-only. To change anything, regenerate (which produces a new DRAFT).

The prompt panel (2026-10-10)

Every generation keeps the prompt it was made from, and its page shows it at every stage — while it is being made, in a reel's stills review, once finished, after it failed, and even after it was archived. Press ▸ Show the prompt & settings to open it:

  • The full prompt, exactly as it was used, with a Copy button.
  • The settings as chips. Images and clips: what made it, the model, quality and shape. Reels: the type (cinematic scenes only), format, look, music, the narration voice if you picked one, and the setting. Carousels: Photographic, Designed or Illustrated (from your brief) slides.
  • ↻ Reuse this prompt opens the matching create screen with the prompt and settings filled in. Nothing is made and no credits are used until you press Generate there.
Made with Prompt shown Reuse opens
AI Studio Image the prompt you generated (or the Image Assistant's draft you picked) Image, with brand, shape and quality
AI Studio Video clip the clip prompt Video clip, with brand and shape
A topic draft (image / clip) the image or video prompt the AI wrote for the topic Image / Video clip with that prompt
AI Studio Carousel your carousel brief (carousels made from 2026-10-10 on; older ones show the per-slide prompts under the carousel instead) Carousel, with brand and style (Photographic, Design or Illustrated — the style the carousel was made with, kept as an explicit choice)
A reel (scene or long-take) your full reel description Create a reel with the description, brand, protagonist, format, look, length, music and voice filled in, on the first step: press Draft my storyboard for a fresh storyboard. (↻ Reuse this reel under a finished reel still brings the whole storyboard too.)
An AI image edit / expand / background change the edit instruction copy only: an edit needs its source image
An ad (Generate a new background) the ad concept, on the ad's page a new ad in the same campaign, on Generate, with the concept and brand

The prompt also travels with the file: a finished reel's video (and its caption-free master) carries its prompt and settings, like every AI image and clip. When a post's media is replaced by an edit of an AI file (an Edit render, on-screen text baked into a clip), the panel falls back to the prompt of the file it was edited from.

Editing and approving a draft

When the status is DRAFT, you can edit any of:

  • Instagram caption — recommended 80–200 words; word + character counter shown live
  • Facebook caption — recommended 100–300 words; live count
  • TikTok caption — recommended 40–150 words; live count
  • YouTube (optional) — a single-line Title (≤100 chars, char counter) and a Description (≤5000 chars, char counter). These aren't required to approve; leave them blank if you never post to YouTube. When set, the YouTube publisher uses them instead of deriving a title/description from the shared caption.
  • Hashtags — comma- or space-separated, with or without #. Your capitals are kept (#SunsetVibes); spaces, symbols and accents are tidied (#Sunset Vibes → #SunsetVibes, Décor → Decor) and a case-only duplicate is dropped. Live chip preview below the input shows exactly what will be saved.
  • Call to action — optional one-line; leave blank to omit

Validation matches what the AI produces (same min/max + format rules). If your edits are out of bounds, the save fails with a clear "Couldn't save — …" message in the modal so you can fix it.

Two paths to ready:

  • Click Approve for posting without editing anything → flips to READY immediately
  • Make any edit, then click Save & approve → saves your edits and flips to READY in one transaction

What approving needs (2026-10-08). At least one platform has to be complete: an Instagram or Facebook caption (40+ characters), a TikTok caption (20+), or a YouTube title. You do not have to write captions for platforms you will not post to, and hashtags are optional. The per-field maximums are unchanged. When you then publish or schedule, every account you tick must have its own content (its caption, or for YouTube a title); if one does not, the dialog closes, the message says which platform needs what, and the page scrolls to that field. Nothing is published half-filled.

If you want to keep editing without committing to approving yet, click Save changes — your edits persist, but the status stays DRAFT.

Once READY, the generation is eligible for scheduling (Scheduler ships in Sprint 4). You can still regenerate a READY generation if you change your mind — that'll produce a new DRAFT linked to the same topic.

Regenerating

Click Regenerate on any generation. Same blocking modal, same wait, same result type — a fresh draft from the same topic + brand + campaign context.

The current implementation (v1) does a full regenerate: every field is re-drafted. Locked-field regen ("keep the image, just rewrite the caption") ships in Sprint 6 — you'll be able to pin specific fields from the parent before regenerating.

Regenerated drafts share lineage with their parent (iteration tree) and cost 0.5× credits vs. the original.

Iterating a video. Use Iterate (top-right) with the Lock video / Lock text toggles. Locking the video and regenerating text only is instant. Regenerating the video itself runs asynchronously: the new draft appears immediately as "Generating…", the video renders in the background (you can navigate away), and the page updates when it's ready — credits are only charged when the video succeeds. (This matches how AI Studio and topic video generation work, so a long render never blocks or times out.)

The Generations list

/generations is the list of every generation in your workspace. Each row shows:

  • The generation's name (link) — its descriptive title, falling back to the topic title or a type label for older posts
  • Status badge — amber DRAFT stands out, green READY, red FAILED, grey ARCHIVED
  • A meta line: {date} · {type} · {source} · #{seq} — e.g. "Jun 18 · Image · AI Studio · #014". Source shows the campaign or brand name for topic posts, or "AI Studio" for from-scratch / uploaded posts. The source-topic link appears only when there is one.

Use this view to find a specific draft by name, see which topics have been drafted recently, or scan for FAILED generations that need a retry.

How the AI generates a post

The AI prompt is built from:

  1. Brand context — voice persona, tone, tone adjectives, forbidden words (effective brand: topic > campaign > none)
  2. Campaign context — name + brief, if the topic has a campaign
  3. Topic context — title, description, AI context

The AI is instructed to:

  • Write each platform caption in that platform's idiomatic style (Instagram warm/story-led, Facebook longer-form/conversational, TikTok punchy/hook-first)
  • Generate 3–15 hashtags in CamelCase (e.g. SmallBusinessTips), no spaces, no # prefix
  • Write a CTA only when natural for the topic (otherwise omit)
  • Draft a specific image prompt — no text-in-image instructions

Provider redundancy: if Anthropic Claude (primary) is unavailable or rate-limited, VibeDay automatically retries on OpenAI before surfacing an error. You'll see "Our AI providers are busy right now" only when both are unavailable.

What happens if the image fails

Text and image are generated in sequence. If the image step fails (timeout, content policy, provider outage), your text is still saved as a draft. The image card on the detail page will show:

No image yet. The image step didn't complete (timeout, content policy, or provider hiccup). The text of this draft is saved — retry the image when you're ready.

With a green Generate image button. Click it to retry — the AI will re-illustrate from the same prompt. You can retry as many times as needed.

You can also approve a draft without an image if you'd rather publish text-only (less optimal for engagement on visual platforms, but supported).

Tips

  • Don't approve the first draft blindly. Read all three platform captions; the AI sometimes nails Instagram and misses TikTok. Regenerate if needed.
  • Use Regenerate to explore. Each regen produces a different angle on the same topic. Two or three regens often gets you a great post.
  • Watch the image prompt. Even before image generation ships, the image prompt is a tell — if the prompt is generic, the topic might be too vague.
  • Approve drafts you might use later, not just ones you're about to publish. READY is a "good enough to schedule" signal, not "scheduled now."

Published state + publish history (2026-08-21)

"View post" links (fixed 2026-08-23). A row links out when the publication has an externalPostUrl. Facebook and YouTube build one from the id they return, but the other two could not, and nothing ever backfilled them — so TikTok and Instagram rows showed a publish time and then nothing, next to a Facebook row that had a link. Now: Instagram fetches its permalink after publish (an IG permalink is a shortcode, so it cannot be derived from the media id) — best-effort, and a failure never fails the post; TikTok captures publicaly_available_post_id on the confirm poll and builds tiktok.com/@handle/video/{id}. TikTok reveals that id minutes after it reports the publish complete, so it is captured opportunistically and never gated on — a row with no link yet shows "Link pending" with an explanation rather than a blank space. A backfill then resolves it: the stuck-processing-reaper cron (every 15 min) re-checks POSTED TikTok rows that still have no URL and fills it in once TikTok exposes the public id — bounded to 48h after publishing and 25 rows per run, so it can never become a background poller. Past 48h a row keeps "Link pending"; the post is still live.

Once a post has been confirmed published at least once, its badge reads Published (with ×N when it has been published more than once) on both the Generations list and the post's own page, and the list row shows the most recent publish date. The post page adds a publish-history panel: one row per confirmed publish with the platform, the exact date/time, the account it went to, and a View post → link to the live post. Publishing the same post again appends a new row — nothing is overwritten, so the full history is always visible.

Two deliberate details:

  • Only confirmed publishes count. A post still processing on the platform (TikTok Direct Post, Facebook video encoding) is never shown as Published until the platform confirms it went live.
  • Published is a derived state, not a lock. Underneath, the post stays READY, which is what allows you to publish it again — to another platform, another account, or the same one later. Archiving hides the Published treatment.

Deleting a post (2026-08-21)

The Delete button — in the post's header, and on every row of the Generations list — removes a post permanently, along with the files it created in your Library (the storage they used is freed from your plan's quota). The confirm dialog shows exactly what will go — how many files and how much space, plus the post's publish history and any revenue attribution attached to it — and asks you to type DELETE.

Two safeguards:

  • You can't delete a post that's mid-generation, or one with a publish still scheduled. Cancel the schedule first; the dialog tells you which applies.
  • Deleting here does not unpublish. Anything already live on Instagram, TikTok, Facebook or YouTube stays live — delete it on the platform too if you want it gone. The dialog warns you whenever the post has been published.

Deletes are recorded in your workspace's audit log.

Cost messaging consistency (2026-09-08 sweep)

Operator-ratified rule: an AI re-generation of the media itself costs credits and says the number next to the CTA; markup edits (captions, text overlays, trims, crops, worker-only renders) are free and say "included — no credits." The platform-wide sweep enforced this:

  • Wrong-number labels fixed to the canonical draw table (credit-draws.ts values interpolated, never hardcoded): ImageEditor AI edit / expand / background ("2 credits" → 21), Studio video copy ("4 credits" → 156), Studio image quality hints (1/2 → 21/42), production RunPalette tier notes (1–2 → 290/500 per scene, 21/42 per image), WhatNext iterate badge (now the exact server derivation incl. the half-price window).
  • Carousel pricing brought to ratified canon: the studio carousel commit charged a stale 1 + slides while the create-time quote/preflight already said TEXT_STEP + 21/slide; commit, slide-retry (1 → 21), composer copy and the slide-count derivation on the generation page now all use the canonical formula.
  • AI image regeneration is now a paid edit (operator-ratified): regenerateImageAction pre-flights and charges PICTURE_CREDITS[quality] on success (double-charge-safe — creation flows charge on success, so a failed image was never charged); the button says "(N credits on success)".
  • Numbers added to charging CTAs: reel re-render-at-quality (quoted via quoteReelCredits), video retry ("N credits on success"), ad-creative Recover-layers / Expand-to-fill / Reformat / mode-aware Regenerate (free in ADAPT-crop, priced in GENERATE/expand).
  • "Included — no credits" stamped on free actions: caption transcription, Find-shorts scan + clip creation, editor AI-assist prompt, auto-emoji, Suggest CTAs/hook/Optimize, ad copy generation, slide text apply, carousel builder, caption-studio render.
  • Retired two-meter vocabulary: "reel cr" → "credits" (one currency).

Resolved 2026-09-08 (operator-ratified after independent CFO + VP-marketing agent review): all five adjunct constants moved into credit-draws.ts — thumbnail 21 (picture draw), ad AI rendition 21/format, Auto-Adapt AI fill 21 per unique ASPECT (the worker already charges per aspect — platforms sharing a shape share one render and one charge; free smart-crop stays the default), decompose 6, ad pack base 4 (text step). platform-specs.ts re-exports from canon so the numbers can't drift again. Stale-deploy errors ("Server Action not found" after a deploy under an open tab) are now intercepted in the blocking overlay + toast with refresh-and-retry copy (src/lib/stale-deploy.ts).


Still stuck?

Email support@vibeday.com with what you're trying to do and a screenshot if it helps — we'll write back within one business day.