Write Your First OpenAPI: A Step-by-Step Guide for Beginners
Learn how to create your first OpenAPI file from scratch with easy examples, reusable schemas, and practical tips.

Imagine this. You open a restaurant menu. Each dish has a name, a description, the ingredients you need, and what the final plate looks like. OpenAPI works the same way for APIs. It is the menu card that tells developers what is available, what to send, and what they will get back.
In this article, we will start small and build step by step, explaining every term so you gain confidence to write your own OpenAPI specification.
Step 1: Create the skeleton
openapi: 3.0.3
info:
title: Hello API
version: 1.0.0
description: A tiny API used to learn OpenAPI fundamentals.
servers:
- url: https://api.example.com
description: Production
Explanation
openapi: 3.0.3 → The version of the OpenAPI standard you are using. Think of it as the edition of a rulebook you are following.
info: → Basic details about your API.
title: The name of your API.
version: The version of your API documentation (use
1.0.0style).description: A short text about what your API does.
servers: → Where your API is hosted.
url: The base URL.
description: A short label such as Production or Sandbox.
Step 2: Add your first endpoint
paths:
/hello:
get:
summary: Return a hello message
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
message: { type: string }
example:
message: "Hello World"
Explanation
paths: → Section listing all your endpoints.
/hello: → The endpoint path, which will be added to the server URL.
get: → The HTTP method (GET means fetch data).
summary: → A short description of what this endpoint does.
responses: → Possible replies from the server.
'200': A success response.
content → application/json: The format of the response.
schema: Defines the shape of the response object.
properties: Lists fields.
example: Shows a sample response.
Step 3: Add a path parameter
/hello/{name}:
get:
summary: Return a personalized hello message
parameters:
- in: path
name: name
required: true
schema: { type: string }
description: Person to greet
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
message: { type: string }
example:
message: "Hello Gagan"
Explanation
/hello/{name}: →
{name}is a placeholder in the path.parameters: → Extra data the API expects.
in: path → This parameter is part of the URL.
name: The name of the parameter.
required: true → It must be provided.
schema: Type of the parameter (here it is a string).
Example: GET /hello/Gagan returns "Hello Gagan".
Step 4: Add a POST with a request body
/greet:
post:
summary: Return a personalized greeting
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name: { type: string }
required: [name]
example:
name: "Gagan"
responses:
'200':
description: Greeting returned
content:
application/json:
schema:
type: object
properties:
message: { type: string }
example:
message: "Hello Gagan"
Explanation
post: → The HTTP method for sending data.
requestBody: → The data you must send to the server.
schema: → Shape of the JSON object.
required: [name] → The field
namemust be included.
Example request: { "name": "Gagan" }
Example response: { "message": "Hello Gagan" }
Step 5: Add reusable components and error handling
components:
schemas:
ValidationError:
type: object
properties:
status: { type: string }
type: { type: string }
code: { type: string }
message: { type: string }
required: [status, type, code, message]
Use it in a response:
responses:
'400':
description: Validation error in the request
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
example:
status: "error"
type: "validation"
code: "NAME_REQUIRED"
message: "name is required"
Explanation
components: → Section for reusable parts.
schemas: → Define reusable object shapes.
$ref: → A reference to a schema defined in components.
Step 6: Add security with an API key
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
security:
- ApiKeyAuth: []
Explanation
securitySchemes: → Defines authentication methods.
type: apiKey → The API key method.
in: header → The key must be sent in the HTTP header.
name: X-API-KEY → The name of the header.
security: → Applies the scheme to all endpoints.
Step 7: Common mistakes beginners make
Writing
requestbodyinstead ofrequestBody(case-sensitive).Using tabs instead of spaces. YAML only accepts spaces, use 2 spaces per level.
Nesting
'400'inside'200'by mistake.Putting endpoint URLs in
serversinstead of only the base domain.Confusing API version with spec version. Keep
info.versionas1.0.0and use/v1style only in paths.
Step 8: Try it in Swagger Editor
Open Swagger Editor.
Paste your YAML.
See your text convert into interactive documentation.
Click File > Save as YAML.
Indentation warning: If you see odd errors such as “responses200descriptionOK,” it usually means your indentation is wrong. Use 2 spaces, not tabs.
Final challenge for you
Add a new endpoint:
POST /feedbackRequest body:
{ "email": "...", "message": "..." }Response:
{ "status": "received" }Error: Reuse the
ValidationErrorschema.
Paste it in Swagger Editor and test. If it renders correctly, you have successfully written your own OpenAPI specification.