TL;DR: The best api design prompts give the model your resource nouns, relationships, and conventions, then ask for one deliverable: a resource model, an OpenAPI document, or a Problem Details error shape. A model drafts a valid contract fast, but cannot know your real consumers, so its output is a proposal to review, not a decision to ship.
What Does "Prompting for API Design" Actually Mean?
Prompting for API design covers the layer above the code: what resources exist, what an endpoint is named, what shape a request or response takes, what an error looks like when something goes wrong. It is not "write me the Express route handler." That's an implementation prompt, and it's a different job with a different failure mode.
The reason this layer is worth a prompt of its own is that it's where a structured output actually matters more than a clever one. An API design output has one job: to be readable by both a human reviewer and, eventually, a code generator or an API client SDK tool. A model that produces prose describing an API is not useful here. A model that produces a resource list, or an OpenAPI document, or a table of endpoints and status codes, is.
This is also where the term contract-first comes from: you settle the shape of the interface, the "contract" between whoever builds the server and whoever builds the client, before either side writes implementation code against it. AI is a genuinely good fit for the first draft of a contract, because a contract is exactly the kind of document a model is good at producing quickly. It's a bad fit for deciding what that contract should promise long-term, because that depends on consumers and history the model was never shown.
How Do You Structure a Prompt for a REST Resource Model?
Before you ask for any OpenAPI YAML, get the model to propose the resource model in plain language first. Skipping this step is the single most common reason an AI-drafted API design has good syntax and a wrong shape: the model jumped straight to endpoints without ever stating what it thought your resources were, so nobody caught the mismatch until the YAML was already written.
A resource-modeling prompt should give the model your domain, your existing naming conventions, and explicit permission to flag guesses instead of making them:
Role: You are a REST API designer, not an implementer.
Task: Propose a resource model for the domain below. Do not write any code.
Domain: <2-4 sentences describing the entities and how they relate to each other>
Constraints:
- Reuse these existing resource names if they overlap: <list, or "none yet">
- Path nesting: no more than 2 levels deep
- Naming: plural nouns, kebab-case paths, camelCase JSON fields
Format: a list of resources. For each one, give its main fields, its
relationships to other resources, and the actions (verbs) it needs to
support. Flag anything you are guessing at as an open question rather
than deciding it silently.
If your API already has a handful of live endpoints, give the model one or two of them verbatim as examples of your existing style rather than describing the style in prose. That's few-shot prompting applied to conventions instead of content, and it works better than adjectives like "RESTful" or "clean," which every model already claims to be following by default.
Can AI Actually Write a Valid OpenAPI Document?
The current specification is OpenAPI 3.1.1, published 24 October 2024. Its own introduction describes what it's for: it "defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic." That's the whole point of asking for one instead of a Word document: the output is machine-checkable.
OpenAPI 3.1 also aligns its schema keywords with JSON Schema Draft 2020-12, which matters practically: it means a model that already knows how to write a JSON Schema (a very common training target) can carry that knowledge straight into your paths and components.schemas blocks, using the same JSON vocabulary, without you having to teach it a separate dialect.
Here's what a single resource looks like once a model turns a resource-model answer into an actual document. This is illustrative, not a template to paste into a real service without renaming everything:
openapi: 3.1.1
info:
title: Widget Catalog API
version: 1.0.0
paths:
/widgets/{widgetId}:
get:
summary: Retrieve a widget by ID
parameters:
- name: widgetId
in: path
required: true
schema:
type: string
responses:
"200":
description: A single widget
content:
application/json:
schema:
$ref: "#/components/schemas/Widget"
"404":
description: Widget not found
content:
application/problem+json:
schema:
$ref: "#/components/schemas/ProblemDetails"
components:
schemas:
Widget:
type: object
required: [id, name]
properties:
id:
type: string
name:
type: string
ProblemDetails:
type: object
properties:
type:
type: string
title:
type: string
status:
type: integer
detail:
type: string
instance:
type: string
That parses. Whether widgetId should actually be a string or a UUID-typed field, whether 404 is the right code for "not found" versus "not visible to this caller" (it usually is, but not always), and whether your real API already calls this resource something else entirely, none of that is something the spec's own validity check will catch. A linter tells you the document is well-formed. It doesn't tell you it's true.
Do You Need Hypermedia, or Is Level 2 Good Enough?
This is a decision worth making explicit in your prompt, because if you don't, the model will guess, and it will usually guess inconsistently across endpoints in the same document.
The reference point here is the Richardson Maturity Model, a framework Martin Fowler wrote up in an 18 March 2010 article, crediting it to "A model (developed by Leonard Richardson) that breaks down the principal elements of a REST approach into three steps." Fowler's write-up walks through the levels in order. Level 1 is about introducing resources at all, moving "rather than making all our requests to a singular service endpoint" toward "talking to individual resources." Level 2 is about verb discipline: "using the HTTP verbs as closely as possible to how they are used in HTTP itself", so GET, POST, PATCH and DELETE mean what HTTP says they mean rather than being tunneled through a single POST endpoint with an action field. Level 3 adds "the ugly acronym of HATEOAS (Hypertext As The Engine Of Application State)": responses that include links telling the client what it can do next, instead of the client hardcoding that knowledge.
Most internal and partner APIs stop at Level 2 and are better for it. Level 2 is what nearly every HTTP client library, API gateway, and monitoring tool already assumes. Level 3 earns its cost on APIs that need to evolve their available actions without breaking every client that hardcoded a URL, typically large public APIs with client software you don't control. If you're not in that position, say so in the prompt: "Level 2 only, no hypermedia links unless I ask for them" is one sentence that saves you from reviewing a response object with a _links block nobody asked for.
How Should AI Design Your Error Responses?
Left alone, most models default to inventing an ad hoc {"error": "something went wrong"} shape, different on every endpoint, sometimes different within the same document if you generate it in pieces. There's a standard shape you can ask for instead: RFC 9457, "Problem Details for HTTP APIs", published July 2023 and obsoleting the earlier RFC 7807. Its abstract states the goal directly: the RFC defines what it calls a problem detail "to carry machine-readable details of errors in HTTP response content to avoid the need to define new error response formats for HTTP APIs."
The format is five members, type (a URI identifying the problem type), status (the HTTP status code, advisory only, since the real header still governs), title, detail, and instance, plus room for your own extension fields when a specific error needs more context than that. A response for the widget example above might look like this:
{
"type": "https://api.example.com/problems/widget-not-found",
"title": "Widget not found",
"status": 404,
"detail": "No widget exists with id 'W-1029'.",
"instance": "/widgets/W-1029"
}
Naming RFC 9457 explicitly in your prompt, rather than describing what you want in your own words, does real work: it gives the model a fixed target instead of an invented one, and it means every endpoint in the document, no matter how many separate prompts it took to generate, fails in the same shape.
Ad Hoc, OpenAPI, or JSON:API: What Should You Actually Ask For?
There's a real decision buried in "just make it a REST API," and it's worth naming out loud before you prompt for it. JSON:API describes itself plainly: it "is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests", and it exists because it "is designed to minimize both the number of requests and the amount of data transmitted between clients and servers." The current version is 1.1, and it requires the application/vnd.api+json media type for anything that follows it.
That's a meaningfully bigger commitment than "return some JSON," and it's worth being explicit about which lane you're asking the model to build in:
| Feature | No convention specified | OpenAPI 3.1 only | OpenAPI 3.1 + RFC 9457 + JSON:API |
|---|---|---|---|
| Machine-readable request/response shapes | |||
| Standardized error format across endpoints | |||
| Standardized pagination and relationship shape | |||
| Can drive codegen for client SDKs or mocks | |||
| Still needs a human to check naming and paths |
For a small internal API with one consumer team, plain OpenAPI without JSON:API is usually the right amount of ceremony. JSON:API earns its overhead when you have multiple independent client teams who would otherwise each invent their own pagination and relationship conventions, and you'd rather point them all at one spec than referee that argument repeatedly.
How Do You Prompt for API Versioning Decisions?
This is the question a model is least equipped to answer well on its own, and the one it will answer most confidently if you let it. Ask "how should I version this API?" with no other context and you'll get a tidy comparison of URI versioning, header versioning, and content negotiation, none of which is wrong exactly, and none of which has any bearing on whether your specific decision is safe.
The missing piece is always the same: who is already calling this API, and what have you promised them. A model reading your prompt has no visibility into your existing consumers, your support inbox, or the partner who integrated against an undocumented field two years ago and never told anyone. So don't ask it to choose a versioning scheme. Ask it to sort a proposed change:
Here is my current endpoint (paste the OpenAPI path item).
Here is my proposed change (describe it).
Consumers I know about: <list, or "none confirmed">
Classify the proposed change as breaking or additive for an existing
consumer who only reads the current documented fields. List every
reason it could be breaking, even ones that depend on a consumer
doing something the docs don't recommend but don't forbid either.
That reframes the model's job from "decide" to "enumerate risk," which is a task it's genuinely useful for. The decision about which risks are acceptable, and which version scheme fits your team's release process, is still yours.
What a Generated API Design Can't Know About Your API
A model can produce a resource model, a syntactically valid OpenAPI document, and error responses shaped to a named RFC, all in the time it takes to read this sentence. What it cannot do is know your API's actual history: which fields a partner is silently depending on, which endpoint your mobile app still calls under the old name because nobody got around to migrating it, what your team already decided about pagination three APIs ago and never wrote down anywhere the model could read it.
That's not a caveat to skim past. It's the difference between a generated design being useful and being dangerous. The safest way to use any of the prompts in this post is to run the output back through your own review process the same way you'd review a junior engineer's first draft of an interface: assume the shape is plausible, assume specific details are wrong until checked, and assume nothing about versioning or backward compatibility without confirming it against consumers you can actually name. If you want a second AI pass before a human reviewer sees it, our guide to prompting for a genuinely useful code review covers how to get a model to critique a draft instead of just approving it.
A Prompt Template You Can Copy and Adapt
Once you've settled on a resource model, a maturity level, and an error format, you can fold the whole decision set into one prompt instead of making the same choices over again for every new endpoint:
You are helping me design a REST resource, not implement it.
Domain: <describe the resource and its relationships in 2-3 sentences>
Existing conventions to match: <naming, auth header, pagination style
already in use elsewhere in this API, or "none established yet">
Maturity target: Level 2 (resources + HTTP verbs), no hypermedia
links unless I ask for them
Output format: an OpenAPI 3.1 path item for <resource>, covering
GET (single), GET (list, paginated), POST, and PATCH
Error format: RFC 9457 Problem Details (type, title, status, detail,
instance)
Constraints: do not invent field names I have not given you. Where
you need a decision I have not specified, list it as an open
question instead of guessing.
Give me the OpenAPI YAML only, followed by a short list of decisions
you made that I should confirm.
That last line, the one asking for a list of decisions to confirm, is doing more work than anything else in the template. It turns an unreviewable wall of YAML into a short checklist you can actually read in the two minutes before your next meeting. Once the contract itself is settled, the natural next step is generating tests against it, which is a different prompting problem with its own failure modes; see our guide to prompting for test generation that finds real bugs for that half of the workflow. And if the API design is really one piece of a larger technical spec you're drafting with AI, the broader discipline is covered in our guide to prompting for technical specs and design docs.
If you'd rather not hand-assemble the role/task/format/constraints structure every time, running your raw notes through a JSON prompt generator or reading our breakdown of how JSON prompts work will get you most of the way to a reusable template faster than building one from scratch.
Stop rewriting prompts. Start shipping.
Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.
Create An Account