How to

How to build a content calendar with approvals

A post goes live with a claim legal never saw, and the calendar is three tabs in a spreadsheet. Here is the model behind a calendar with approvals, the prompts to build it, and what it takes to run it.

The short answer

A content calendar with approvals is four parts: one calendar for every channel, review routed by what the content contains, feedback that has to be resolved rather than just read, and a record of what published. The rule that prevents the worst outcome is content-driven routing. A post containing a customer name, a performance claim or a pricing statement needs a specific reviewer, and relying on the author to remember which is how uncleared claims get published.

content-calendar.helix-app.ai

Content calendar

31

Scheduled this month

6

Waiting on review

2

Approvals invalidated

48

Pre-approved claims

September 2026

Mon
Tue
Wed
Thu
Fri
1
Blog: benchmark
2
3
Email: Q4 pricing
4
5
8
Social: hiring
9
Halden case study
10
11
Launch press
12
15
16
Webinar invite
17
18
Blog: how-to
19
22
Newsletter
23
24
Product update
25
26
A sketch of the month, every channel on one calendar. The three highlighted items are the ones review is waiting on, routed there by what they contain rather than by anyone remembering to ask.

What matters here

  • A content calendar with approvals is four parts: one calendar, content-driven review routing, resolvable feedback, and a published record.
  • Route review by what the content contains, not by who usually reviews. Customer names, claims and pricing each have a specific approver.
  • One calendar for every channel. Separate calendars per team is how two campaigns land on the same day.
  • Feedback needs a resolvable state. A comment thread with no resolution is how a required change gets missed.
  • Approvals must be bound to a version. Approving a draft that is then edited is the most common failure in any review process.
  • Keep what actually published, separately from the plan. Six months later the question is what went out, not what was scheduled.

Who this is for

You run content, marketing operations or brand. You already have a calendar and an approval process, probably in different places. What you want is for review to happen automatically where it is needed and nowhere else.

How it works in practice

How a piece of content gets from an idea to a published record, and what stops the wrong claim going out.

  1. 1

    Everything sits on one calendar

    Blog, email, social, web, events, launches and paid. Separate calendars per team is how two campaigns land on the same day.

  2. 2

    The author answers a short checklist at submission

    Does it name a customer, make a claim, mention pricing, commit to future functionality, quote someone, use a partner brand.

  3. 3

    The draft gets scanned as a safety net

    Percentages, superlatives, currency amounts and known customer names. A mismatch with the checklist is flagged for the author to confirm.

  4. 4

    Reviewers are derived, not chosen

    The author never picks who reviews. Remembering which reviewer a claim needs is precisely what fails.

  5. 5

    Feedback has to be resolved, not just read

    Required change, suggestion or question, each with a state. Approval is blocked while a required change is open.

  6. 6

    Editing after approval invalidates it

    And says which approvals and why. That single rule prevents a whole class of problem.

What a content calendar is made of

A content calendar with approvals is not a spreadsheet with a status column. It is four parts, and the second is what stops an uncleared claim reaching a customer.

One calendar

Every channel in one view: blog, email, social, web, events, product announcements, and paid. With owner, status, target date and campaign.

Content-driven routing

Review requirements derived from what the piece contains and where it will run: a customer name, a performance claim, pricing, a product commitment, or a regulated topic.

Resolvable feedback

Each comment has a state and an owner, and required changes must be resolved before approval. A thread with no resolution is how a required change gets missed.

A published record

What actually went out, when, at what URL, in what final version, with the approvals attached. Separate from the plan, because the two diverge.

These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix

The prompts

Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.

  1. One calendar, every channel

    Because separate ones are how collisions happen.

    In this Helix project, build me a content calendar with approvals.
    
    One record per item: title, type, channel, campaign, author, owner, target
    publish date, actual publish date, status, audience, primary message, url,
    and a link to the draft.
    
    Types to seed: blog post, email, social post, landing page, press release,
    customer story, product announcement, webinar, paid ad.
    
    Give me a calendar view filterable by channel, campaign, owner and status,
    and a list view for people who prefer one. One calendar covering every
    channel, with filters, rather than one per team. Separate calendars are
    how two campaigns land on the same day and how an email goes out before
    the page it links to.
    
    Add conflict detection: more than one item in the same channel on the same
    day, or two items aimed at the same audience in the same week. Warn, do
    not block.
    
    And a campaign view that groups every item in a campaign with its
    dependency order, so it is obvious when something is scheduled out of
    sequence.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
  2. Route review by what the content contains

    Not by what the author remembers.

    Now the rule that prevents the worst outcome.
    
    Put review rules in a config file. Each has a trigger and the reviewer role
    it requires. Seed it with: names a customer, makes a performance or
    comparison claim, mentions pricing, commits to future functionality, quotes
    a person, uses a partner or third-party brand, touches a regulated topic,
    targets a regulated market.
    
    The author answers a short checklist at submission and the app derives the
    required reviewers from the answers. Do not ask the author to pick
    reviewers. Relying on memory is exactly the failure this exists to
    prevent.
    
    Then add a safety net: scan the draft for signals that contradict the
    checklist, like a percentage, a superlative, a currency amount, or a
    customer name from a list I maintain. Flag any mismatch for the author to
    confirm before submitting.
    
    Show the author which reviewers their answers triggered and why. Route
    reviews in parallel where they are independent, in sequence where one
    depends on another.

    Worth knowing. The text scan is a net, not a gate. Authors answer checklists optimistically, and a flagged mismatch costs one confirmation click.

  3. Feedback that cannot quietly go unaddressed

    And approvals that mean a specific version.

    Reviewers see the draft, the checklist answers, why they were routed in, and
    what they are being asked to confirm. A legal reviewer looking at one claim
    should not have to read a whole blog post to find it.
    
    Give comments a type: required change, suggestion, or question. Each has a
    state of open or resolved and an owner. Approval is blocked while any
    required change is open. A suggestion never blocks.
    
    Then the rule that prevents a whole class of problem: bind approvals to a
    specific version. Editing a draft after approval invalidates the affected
    approvals and says which and why. It is unpopular for about a week and
    then nobody wants to go back.
    
    Add deputies per reviewer role with automatic reroute, and derive a due
    date on every review from the publish date minus a lead time I configure
    per content type. Give the author one view of everything outstanding and
    who holds it.

    Worth knowing. Approving a draft that is then edited is the most common failure in any review process, and it is one rule to prevent.

  4. The published record, and how to need less review

    What went out, and the claims library that shrinks the queue.

    On publish, record the actual date, the final version, the live url, and the
    approvals in place at that moment. Keep that separately from the planned
    item, because plans and reality diverge and the record is what matters
    later.
    
    Make the archive searchable by claim type, customer named, and campaign.
    When a customer relationship changes or a claim is retired, "where have we
    said this" needs an answer in minutes.
    
    Report published against planned by month and channel, average time in
    review by reviewer role, and items published without a required approval,
    which should be zero. Plus the most frequently triggered review rules.
    
    Then use that last report to build a pre-approved claims library:
    statements already cleared, with expiry dates, that authors can use without
    triggering a review. Most review load is the same claims being cleared over
    and over, and this is where the time comes back.
  5. Connect it to real systems

    The step that turns a working prototype into something with your data in it.

    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Google Drive>. Read the draft to scan for claims, customer names and
    pricing, which is the safety net under the checklist.
    
    <Okta>. Resolve reviewer roles, so an approval carries a verified
    identity.
    
    <Contentful>. Read what actually published and when, and the live url for
    the record.
    
    <Slack>. Route reviews and chase them against the lead time for that
    content type.
    
    <Google Analytics>. Attach performance to each published item, so the
    archive is not just a record.
    
    <Notion>. Read drafts where writers actually work, rather than asking them
    to move.
    
    <Gmail>. Send the review request with the specific claim highlighted, not
    the whole post.
    
    <Snowflake>. Keep the published record queryable, so where-have-we-said-
    this is a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.

    Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.

  6. Ship it

    The last step of every build: a URL, and the right people on it.

    Deploy my app.

    Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. Unpublished plans and legal review comments are confidential, and an approval is only evidence if the identity behind it is verified. Set Access Control before sharing.

What it connects to

Routing review by what the content contains means the app has to see the draft.

  • Google Drive

    Read the draft to scan for claims, customer names and pricing, which is the safety net under the checklist.

  • Okta

    Resolve reviewer roles, so an approval carries a verified identity.

  • Contentful

    Read what actually published and when, and the live url for the record.

  • Slack

    Route reviews and chase them against the lead time for that content type.

  • Google Analytics

    Attach performance to each published item, so the archive is not just a record.

  • Notion

    Read drafts where writers actually work, rather than asking them to move.

  • Gmail

    Send the review request with the specific claim highlighted, not the whole post.

  • Snowflake

    Keep the published record queryable, so where-have-we-said-this is a query.

Each line says whether the app reads, writes or both. Anything not described as writing should be read only.

Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.

Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.

Running it for real

The build gets you a working calendar. It holds unpublished plans and the approval record behind public claims, so how it is run matters.

AI Deployment

Get it to a URL people can open

One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.

App Security

Put your identity provider in front of it

Unpublished plans and legal review comments are confidential, and an approval is only evidence if the identity behind it is verified. SSO verifies the identity behind an approval, and scoped access keeps the plans and the comments to the people reviewing them.

App Security

Connect the system of record with managed credentials

Pulling analytics for published items and pushing scheduled content to publishing tools needs real access. Granting it to the app rather than pasting keys into it means credentials can be rotated or revoked without a redeploy.

App Registry

Put a name on it

Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.

Cost Management

Know what it costs to run

Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.

Questions people ask

How should content review be routed?

By what the content contains, derived from a short checklist the author completes at submission, not by the author choosing reviewers. Customer names, performance claims, pricing and forward-looking statements each have a specific reviewer, and remembering which is exactly what fails.

Why should approvals be bound to a version?

Because approving a draft that is then edited is the most common failure in any review process. Invalidating the affected approvals on edit, and saying which and why, is one rule that prevents a whole class of problem.

What is wrong with comment threads for review feedback?

Nothing has a state. A required change and a passing suggestion look identical, and neither has to be resolved before publishing. Typing each comment as required, suggestion or question, with an open or resolved state, fixes it.

Should the calendar cover every channel?

Yes. Separate calendars per team is how two campaigns land on the same day and how an email goes out before the page it links to. One calendar with filters gives each team its own view without splitting the data.

How do I reduce content review load?

Build a library of pre-approved claims with expiry dates that authors can use without triggering review. Most review work is the same statements being cleared repeatedly, and the report on most-triggered rules tells you which ones to add.

Can I build this without an engineering team?

Yes. The prompts here are written for Claude Code, Codex or Cursor and stage the build. The judgement calls are your review rules and your lead times per content type.

Last reviewed September 2026.

Build it, then run it properly

Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.