The standard user story template is one sentence: "As a [specific user], I want [one capability], so that [real benefit]." A story is ready to build when that sentence is paired with two to five acceptance criteria that could fail, and it passes the six INVEST checks: Independent, Negotiable, Valuable, Estimable, Small, Testable.
That is the short answer. The rest of this guide gives you a template you can paste straight into Jira or a doc, 14 sample user stories from different domains, and the checks that separate a story someone can build from one that just looks tidy.
It matters more than it used to. A vague user story used to cost you a five-minute conversation at standup. Now it costs you 400 lines of confidently wrong code. If you build with Lovable, Bolt or Cursor, your user stories are the closest thing to a contract your AI pair has, and it will honour every gap in them literally.
What is a user story?
A user story is a short, plain-language description of a feature from the point of view of the person who wants it. It names who the feature is for, what they want to do, and why they want to do it. It deliberately leaves out how the feature gets built.
Stories replaced long requirement documents in agile teams because they are cheap to write and cheap to change. Ron Jeffries described the idea with three C's:
- Card. The story itself, short enough to fit on an index card.
- Conversation. The discussion between the people who want the feature and the people building it, where the details get worked out.
- Confirmation. The acceptance criteria that prove the story is done.
The card is the part everyone copies. The confirmation is the part everyone skips, and it is the part that decides whether the story is any use.
The user story format, part by part
The three-part format is often called the Connextra format, after the London team that popularised it in the early 2000s. Each part has a job.
As a [role]. Who benefits. Make it a specific person in a specific situation: "returning patient", "clinic owner", "freelance translator". "User" is almost always a sign the writer has not decided who this is for. If you have personas, use their names here (the guide to personas for product teams covers how to make them worth naming).
I want [capability]. One thing the person can do, described as a need rather than a solution. "Search recipes by ingredient", not "an Elasticsearch-backed search bar". If you need the word "and", you probably have two stories.
So that [benefit]. Why it matters to them. This is the clause that tells the builder which trade-offs are acceptable. A common failure is a benefit that just restates the capability: "I want to export invoices so that I can export my invoices." If you cannot finish the clause honestly, you are looking at a task, not a story.
The sentence is the headline. On its own it is not enough to build from, which is why the template below carries more than one line.
Copy-paste user story template
This is the agile user story template I use. Paste it into a Jira description, a Notion page or a Google Doc. The first lines are the classic format; the rest is what stops a builder (human or AI) from guessing.
Title: <verb + object, e.g. "Duplicate a past invoice">
Story:
As a <specific role in a specific situation>,
I want <one capability>,
so that <the real benefit to that person>.
Acceptance criteria:
1. Given <starting state>, when <action>, then <observable result>.
2. Given <edge case>, when <action>, then <observable result>.
3. Given <error or permission case>, when <action>, then <observable result>.
Edge states:
- Empty: <what shows when there is no data yet>
- Loading: <what shows while waiting>
- Error: <what the user sees and can do>
- No permission: <what happens, or "deferred">
Depends on: <stories or systems that must exist first, or "none">
Out of scope: <the obvious next thing this story does NOT include>
Size: <S / M / L, or your points scale>
Two fields earn their place more than they look like they should. Out of scope stops the most likely misreading before it happens: "duplicate an invoice" does not mean "edit recurring billing schedules". Depends on forces you to notice when a story is not really independent, which saves a stalled sprint later.
If you want the one-line version for a sticky note or a quick backlog pass, it is just the story sentence plus one acceptance criterion:
As a <role>, I want <capability>, so that <benefit>.
Done when: <one condition that could fail>.
Is there a template for Jira user stories? Jira's Story issue type gives you a summary and a description field, so the title goes in the summary and the rest of the template goes in the description. Some teams add acceptance criteria as a custom field or a checklist. The structure matters more than where it lives. If you plan in VibeMap, the stories stay in one linked spec that your coding agent reads directly over MCP, and you can download the full development spec as markdown.
Why most user stories fail before anyone writes code
Most stories fail one of three ways. They describe a solution instead of a need ("add a dropdown"). They bundle several features into one card ("users can manage their account"). Or they leave out the condition that would make them checkable ("the page should load fast").
The symptom is the same in all three cases: the builder fills the gap with an assumption. The difference now is what happens next. A human teammate surfaces the mismatch at standup, usually as a slightly annoyed question. An AI tool ships the assumption immediately, styled and plausible and indistinguishable from the thing you meant.
Consider Priya, a solo PM building booking software for physiotherapy clinics. Her backlog contains this:
Bad: "As a user, I want a better dashboard, so that I can see my stuff."
Every word defers a decision. Which user? Better than what? Pasted into Bolt, it cheerfully generates a dashboard: a generic grid with invented revenue charts. The tool did not fail. The story did.
This is the amplification problem from what vibe coding actually is. AI tools scale input quality in both directions. Longer stories do not fix it. Stories that pass six tests do.
User story examples: 14 samples across domains
The fastest way to learn the format is to watch weak stories get fixed, then read good ones from contexts you know. The first six are bad-to-good rewrites. The other eight are sample user stories you can adapt, each with its acceptance criteria.
Six rewrites: bad story, good story
These come from three builders. Priya, the solo PM above. Marco, an indie hacker building a recipe app in Cursor. And Dana, a technical founder building invoicing software for freelance translators. The move is the same every time: name a specific persona instead of "user", replace the proposed solution with the underlying need, add the boundary conditions, and finish with something that could fail.
1. Healthcare scheduling (Priya)
Bad: "As a user, I want to book appointments easily." (No persona, no scope, and "easily" cannot be tested.)
Good: "As a returning patient, I want to book a follow-up from my last practitioner's available slots, so that I don't repeat my intake details. Slots reflect calendar changes within 1 minute; double-booking is impossible."
2. Notifications (Priya)
Bad: "As a user, I want notifications so that I don't miss things." (Which events? Which channel?)
Good: "As a clinic owner, I want an email when a patient cancels within 24 hours of their appointment, so that I can offer the slot to the waitlist. It arrives within 5 minutes with a one-click notify-waitlist link."
3. Search (Marco)
Bad: "As a user, I want to search recipes." (By what? What does the empty state look like?)
Good: "As a home cook, I want to search recipes by ingredient, so that I can use what's in my fridge. Matching is case-insensitive, results show within 1 second, and an empty result suggests removing the rarest ingredient."
4. Invoicing (Dana)
Bad: "As a user, I want to manage invoices." (An epic pretending to be a story. Create? Send? Void? Export?)
Good: "As a freelance translator, I want to duplicate a past invoice with a new number and date, so that repeat clients take 30 seconds to bill. Line items copy over, the number auto-increments, and the copy opens in draft state."
5. Payments (Dana)
Bad: "As a user, I want Stripe integration." (Implementation, not need, and unestimable.)
Good: "As a freelance translator, I want each sent invoice to include a payment link, so that clients pay without a bank transfer. Successful payment marks the invoice paid and emails me a receipt within 2 minutes."
6. Onboarding (Marco)
Bad: "As a new user, I want a smooth onboarding experience." ("Smooth" cannot fail a test, so it cannot pass one.)
Good: "As a first-time visitor, I want to save my first recipe before creating an account, so that I see value before committing. The save persists through signup."
Every good version has a named persona, one capability, an honest benefit, and a condition that could fail. That last part is the one AI tools need most. A story that cannot fail a test lets the tool invent its own definition of done, and it will.
Eight sample user stories with acceptance criteria
7. E-commerce: back-in-stock alert
"As a shopper looking at a sold-out size, I want to be emailed when that size is back in stock, so that I don't have to keep checking the page."
- Given a size is sold out, when I enter my email and confirm, then I see "We'll email you when it's back."
- Given the size is restocked, then I get one email within 1 hour with a link to that exact size.
- Given I have bought that size since signing up, then no alert is sent.
8. SaaS registration: email sign-up
"As a new visitor coming from the pricing page, I want to sign up with my work email and a password, so that I can start a trial without talking to sales."
- Given a valid email and a password of 12+ characters, when I submit, then my account is created and a verification email is sent.
- Given the email is already registered, when I submit, then I see "This email already has an account" and a sign-in link, not an error code.
- Given I don't verify within 24 hours, when I click the link, then it says it has expired and offers a new one.
9. B2B SaaS: team invites
"As a workspace admin, I want to invite teammates by email with a role, so that they land with the right permissions on day one."
- Given I enter an email and pick Editor or Viewer, when I send, then the invite appears as Pending in the member list.
- Given the invitee accepts, then they join with the chosen role and I get a notification.
- Given I am not an admin, then the invite button is not shown.
10. Marketplace: host booking requests
"As a host with instant booking turned off, I want to accept or decline a booking request from my phone, so that I don't lose guests while I'm away from my laptop."
- Given a new request, then I get a push notification showing dates, guest count and payout.
- Given I don't respond within 24 hours, then the request expires and the guest is told.
- Given the dates were booked elsewhere in the meantime, when I tap Accept, then I see a conflict message instead of a double booking.
11. Internal tool: support refunds
"As a support agent handling a complaint, I want to issue a partial refund from the order screen, so that I can resolve the ticket without asking finance."
- Given an order paid in the last 90 days, when I enter an amount up to the order total, then the refund is issued and logged on the order with my name.
- Given the amount is over the order total, then the refund button is disabled with the reason shown.
- Given a refund over the agent limit set by finance, then it goes to a manager for approval instead of being issued.
12. Mobile app: offline field notes
"As a field technician in a building with no signal, I want to fill in a job report offline, so that I don't have to rewrite it from memory later."
- Given no connection, when I save a report, then it is stored on the device and marked "Waiting to sync".
- Given the connection returns, then the report uploads without me doing anything and the badge clears.
- Given the job was reassigned while I was offline, then my report still syncs and the office is flagged about the conflict.
13. Content management: scheduled posts
"As an editor, I want to schedule an approved article for a future date and time, so that it goes live when the campaign starts even if I'm offline."
- Given an approved article, when I pick a date and time in my time zone, then it shows as Scheduled with that time.
- Given the scheduled time arrives, then the article publishes within 1 minute.
- Given the article is edited after scheduling, then it returns to Draft and needs re-approval.
14. Personal finance: budget alert
"As someone saving for a house deposit, I want an alert when my monthly takeaway spending passes a limit I set, so that I notice before the month is gone."
- Given a limit of £150 for Takeaways, when a transaction takes the month's total past it, then I get one notification that day.
- Given I am already over the limit, then further transactions that month don't send more alerts.
- Given a transaction is recategorised out of Takeaways, then the total updates and no alert fires retroactively.
Notice what none of these specify: the database, the framework, the UI library. That is the N in INVEST.
The INVEST criteria, letter by letter
INVEST is a checklist for judging story quality, coined by Bill Wake in his 2003 essay INVEST in Good Stories, and SMART Tasks. The letters stand for Independent, Negotiable, Valuable, Estimable, Small, and Testable.
A story that satisfies all six can be built and verified without a clarifying meeting. That is also, not coincidentally, what makes it work as an AI prompt. Here is each letter in practice, with Marco's recipe app.
I is for independent
The story should not secretly depend on unbuilt work. Dependency chains stall sprints, and they badly confuse AI tools, which cannot see your backlog.
Bad: "As a home cook, I want to see comments on my recipe, so that I feel connected." (Silently depends on accounts, recipe pages, and a comment-posting story that does not exist.)
Good: "As a home cook, I want to post a comment on any published recipe, so that I can ask the author questions. Comments require a logged-in account and appear immediately under the recipe."
N is for negotiable
The story is a placeholder for a conversation, not a spec carved in stone. State the what, leave the how open.
Bad: "As a user, I want a React modal with a Formik form and a Postgres upsert, so that I can edit my profile." (An implementation ticket wearing a story costume.)
Good: "As a home cook, I want to update my display name and avatar, so that other cooks recognise me. Changes take effect everywhere my name appears."
V is for valuable
If you cannot finish the "so that" clause honestly, it is a task, not a story. "As a developer, I want to refactor the auth module" is real work. It belongs in a tech-debt lane, not disguised as user value.
E is for estimable
A builder, human or otherwise, has to be able to size it. Stories become unestimable when they hide research ("integrate with whatever calendar APIs exist") or unbounded scope ("support all file types"). If you cannot estimate it, split out a timeboxed spike and estimate that instead.
S is for small
Mike Cohn's guideline at Mountain Goat Software is that a story should fit in a few days. For AI-assisted builds I would tighten that: one story, one focused generation session. If the tool has to touch twelve files across four domains, you have an epic in disguise. Slicing tactics are below.
T is for testable
Every story needs a condition you can check with a yes or a no. "Search should be fast" is a wish. "Search results render within 1 second for a 10,000-recipe catalogue" is a test.
User story vs task, epic and acceptance criteria
These four get mixed up constantly, and the mix-up is usually where scope goes missing.
| What it describes | Written for | Example | |
|---|---|---|---|
| Epic | A large goal made of many stories | Planning and roadmaps | "Invoicing" |
| User story | One capability a specific user gets, and why | The whole team | "Duplicate a past invoice so repeat clients are quick to bill" |
| Acceptance criteria | The checkable conditions that prove the story is done | Builders and testers | "The copy opens in draft with the next invoice number" |
| Task | A piece of technical work needed to deliver a story | Whoever builds it | "Add an invoice number sequence" |
A story describes value from the outside. A task describes work from the inside. If a card has no user in it and no benefit you could say to a customer, it is a task, which is fine; it just shouldn't be dressed up as a story. Acceptance criteria belong to a story, typically two to five per story, often written as Given/When/Then. To get properly good at that layer, the Gherkin guide for PMs has worked examples.
How to slice stories that are too big
Story slicing means splitting a large story into smaller ones that each still deliver something a user can see. The metaphor worth keeping is cutting a cake vertically, through all the layers, rather than horizontally by tier.
"Build the schema," then "build the API," then "build the UI" is horizontal slicing. Nothing is usable until everything ships, and you find out on the last slice whether the first one was right. Vertical slicing gives you thin end-to-end paths instead, each one complete and testable on its own. Atlassian's guide to user stories makes the same point: stories are units of deliverable work, not units of architecture.
Four patterns cover most oversized stories.
By workflow step. Dana's "manage invoices" epic becomes: create a draft, then send by email, then record a manual payment, then void. Each ships alone.
By business rule. "Calculate booking fees" becomes: flat fee, then discounted follow-up fee, then first-visit waiver. Ship the flat fee and the app is usable immediately.
By data variation. Marco's "import recipes" becomes: from a pasted URL, then from a photo, then from a PDF. The URL slice alone is shippable.
By capability level. "Search" becomes: exact match, then multi-ingredient match, then typo-tolerant match. Version one is honest and small.
A quick smell test: if the title contains "manage," "handle," "support," or "system," it is probably an epic. Slice until each story can be generated, reviewed, and merged in one sitting.
Writing user stories with AI
When you build with AI tools, a story stops being a conversation starter and becomes a specification that gets implemented literally, gaps included. Humans fill ambiguity with context and questions. Language models fill it with statistically plausible guesses. Which means INVEST, written in 2003 for human teams, is arguably more valuable now than it was then. Independent stories stop the tool hallucinating dependencies. Negotiable stories let it pick something idiomatic for your stack. Testable stories give it a definition of done it cannot quietly redefine.
The same applies when the AI is writing the stories rather than reading them. Ask an LLM for user stories and you get a tidy list back in seconds, and roughly a third of it will be usable. The rest is fixable, though not by writing a better first prompt. It is fixable by making the model attack its own output.
Why the first draft is mediocre
A model generating user stories is doing pattern completion against a decade of public backlogs, and most public backlogs are bad. The training data is full of "As a user, I want to manage my settings," so that is the shape it reaches for.
There is a second, less obvious problem. The model has no idea what it does not know about your product. A human PM handed a vague brief asks a question. A model handed a vague brief produces confident output at the same fluency regardless of how much context it actually had. You cannot tell from the tone whether it understood you.
Step 1: generate a draft worth critiquing
The goal of the first prompt is coverage, in a format you can pick apart systematically.
Generate user stories for this feature.
Feature: <DESCRIPTION>
Product context: <ONE PARAGRAPH: what the product is, who uses it>
Personas that exist: <NAMES AND ROLES, or "none defined yet">
Format: "As <named persona>, I want <capability>, so that <benefit>."
For each story return:
- persona (must be from the list above, never "the user")
- the story sentence
- size: S / M / L
- scope: frontend / backend / fullstack
- assumptions you had to make to write this story
Rules:
- 3 to 6 stories. Do not pad to hit a number.
- One capability per story. If you need "and", split it.
- Every story needs a condition that could fail.
Output as a JSON array.
The field doing the most work there is assumptions. Models will happily invent scope, and normally that invention is invisible because it arrives in the same confident register as everything else. Asking for assumptions explicitly drags it into the open, where you can read a line like "assumed users can belong to multiple teams" and catch a decision you never made. The second most useful constraint is "do not pad to hit a number". Ask for ten stories and you will get ten, including four that are the same story wearing different verbs.
If you would rather skip writing that prompt, VibeMap's free User Story Generator does step one for you: it turns a plain-English feature description into three to five stories, each with a named persona, a MoSCoW priority and a T-shirt estimate. Steps two and three are still yours.
Step 2: critique with a hostile rubric
This is the step that matters, and the one almost everyone skips. Hand the output back with a specific adversarial role.
Here are user stories you generated:
<PASTE STEP 1 OUTPUT>
Review them as a skeptical engineering lead who has to build these.
For each story, answer:
1. Could I build this without asking a single clarifying question?
If no, what exactly is missing?
2. Is this actually one capability, or several bundled?
3. Name a specific way this story could be built technically
correctly and still be wrong.
4. What edge case does this story silently assume away?
5. Is the "so that" clause a real user benefit, or a restatement
of the capability?
Be harsh. Stories that pass everything are suspicious.
Output: for each story, a verdict of KEEP / REWRITE / SPLIT / CUT,
with a one-line reason.
Question 3 is the one that earns its keep. "Technically correct and still wrong" is the exact failure mode of AI-assisted building, and asking the model to predict it surfaces gaps that a checklist review misses.
Asking a model to grade itself sounds like it should be useless, and partly it is: models rate their own output generously when you ask "is this good?" They do much better with a specific adversarial role and concrete questions, because that is a different task. You are not asking for a score. You are asking it to generate objections, which it is genuinely good at. For a stronger version, run the critique in a different model from the one that wrote the stories. The failure modes don't fully overlap, so you catch more.
Step 3: rewrite only what failed
Feed back only the REWRITE and SPLIT verdicts, with the reasons attached. Don't regenerate the whole set, or you lose the stories that were already fine and get a new batch with new problems.
Rewrite only these stories, addressing the specific critique attached:
<PASTE THE FAILED STORIES + THEIR VERDICTS>
Keep the same format. Do not touch the stories that passed.
For splits, produce the separate stories and note any ordering dependency.
Two or three loops is usually where it stops improving. Stop when the remaining objections need information the model does not have. "Would clinic owners actually want this?" is not a question another loop will answer. That is a question for a person who owns a clinic.
Failure signatures in AI-written stories
These patterns are more common in generated stories than in human-written ones, so check for them first.
- The persona is decoration. The story says "As Priya, a clinic owner" but nothing after the comma would change if it said "As Marco, a home cook." Test: swap the persona for a completely different one. If the story still reads fine, the persona is not doing any work.
- The benefit restates the capability. "I want to export invoices, so that I can export my invoices." Easy to miss because it scans as complete.
- Invented scope. Stories referencing features you never described. These arrive in clusters: once the model decides your app has teams, it writes four team stories. The
assumptionsfield catches most of them. - Uniform size. Every story comes back M. Real backlogs are lumpy, so uniform sizing means the model is matching the format rather than reasoning about the work.
- Suspicious completeness. Every story has exactly three acceptance criteria: one happy path, one edge, one failure. Real features are not that symmetrical. Some have one obvious path and eleven ways to fail.
- No dependencies. Generated sets tend to present every story as independent, because Independent is an INVEST letter and the model is optimising for the rubric. Real features have ordering constraints.
In fairness, the model beats most human first drafts in a couple of ways. Once asked, it is more thorough about unglamorous paths: a person writing stories at 4pm skips the permission-denied case, and a prompted model won't. It also doesn't get bored, so story fourteen gets the same attention as story two. And the loop works in reverse: write your own stories, then ask the model to attack them with the same rubric.
Pair every story with acceptance criteria before you build
The handoff that makes AI builds work is pairing every story with explicit acceptance criteria before generation starts. Priya's cancellation story from example 2 gets:
Acceptance criteria:
- Given an appointment starting in <24h, when the patient
cancels, then the owner gets an email within 5 minutes.
- Given an appointment starting in >24h, when the patient
cancels, then no email, it goes to the daily digest.
- Given the email is sent, then it contains patient name,
slot time, and a one-click "notify waitlist" link.
Three lines that eliminate the three likeliest misreadings: emailing on every cancellation, dropping the time threshold, and inventing the email's contents. Generated criteria have their own blind spots, covered in what LLMs skip in acceptance criteria, and the Acceptance Criteria Generator gives you a draft to review.
Stories rarely live alone, either. In VibeMap, user stories sit in a linked spec, with personas and features above them and acceptance criteria, pages and the database schema below, and each artifact traces back to the one that justified it. If that is the direction you are heading, spec-driven development explains the wider workflow, and designing a database schema from user stories picks up where this guide stops.
The pre-build checklist
Ten checks, applied to every story before it enters a sprint or a prompt. Six are INVEST; four are practical additions that catch what INVEST alone misses.
The bar for passing is concrete: a mid-level developer or a competent AI tool could build it without asking a single clarifying question. "Sounds reasonable in refinement" is not the bar.
- Named persona. A specific role in a specific situation, never "user."
- One capability. No "and," no "manage," no bundled verbs.
- Honest benefit. The "so that" would survive being read aloud to a customer.
- Independent. Names its preconditions and depends on nothing unbuilt.
- Negotiable. Describes the need, not the implementation.
- Estimable. Sizable without a research phase.
- Small. Fits one focused session.
- Testable. At least one condition that could fail.
- Acceptance criteria. Two to five Given/When/Then statements: happy path, one edge, one error.
- Edge states. Empty, loading, error, and permission-denied behaviour either stated or explicitly deferred.
FAQ
What are the 3 C's of a user story?
Card, Conversation and Confirmation, a framing from Ron Jeffries. The card is the short written story, the conversation is where the team and the people asking for the feature work out the details, and the confirmation is the acceptance criteria that prove it is done. Most weak stories have a card and nothing else.
Who usually writes user stories?
Usually the product owner or product manager, but anyone close to the user can write one: designers, developers, founders, support staff. What matters is that the people building it get to question it before it is committed to a sprint. On a solo project you write them yourself, which is exactly when a checklist helps most.
What's the difference between a user story and a task?
A user story describes a capability from the user's point of view and says why it matters. A task is a piece of technical work needed to deliver a story, like adding a database column or writing an email template. One story usually breaks into several tasks. If a card has no user and no benefit, it is a task.
How long should a user story be?
The sentence itself is one or two lines. With acceptance criteria and edge-case notes, a well-formed story runs 5 to 15 lines, about the size of the template above once it is filled in. If it needs more, it is usually an epic that wants slicing.
Can AI generate user stories for me?
Yes, and the format will usually be fine. Treat the output as a first draft: models are good at structure and at covering edge cases once prompted, but only you know your users and constraints. Run the generate, critique and rewrite loop above before anything goes into a sprint.
Sources and further reading
- Bill Wake, INVEST in Good Stories, and SMART Tasks: the 2003 essay that coined INVEST.
- Mike Cohn, User Stories Applied: the book that took the role, goal and benefit format mainstream.
- Atlassian, User Stories: Examples and Template: the canonical story structure.
- Cucumber, Gherkin Reference: Given/When/Then syntax.
If you would rather edit a draft than start from a blank page, the User Story Generator turns a plain-English feature description into three to five stories, each with a persona, a MoSCoW priority and a T-shirt estimate. Free, no signup, and the checklist above still applies to whatever comes back. For the acceptance criteria, take each story to the Acceptance Criteria Generator.



