Writing Tutorials in X402
By X402 Team | Last Updated: February 2026
Direct Answer
Tutorials in X402 are step-by-step learning experiences organized in batches, following a goal-driven structure with prerequisites, tested steps, and verification checkpoints. Each tutorial guides learners from zero to a working result through hands-on practice.
Overview
Tutorials are the most effective way to teach new users how to accomplish specific tasks. Unlike reference documentation or conceptual guides, tutorials are learning-oriented: they take a beginner from start to finish on a practical project.
Tutorial vs Other Content Types
Tutorial (Learning-Oriented)
Goal: Teach through doing Example: "Build a REST API in 30 Minutes"- Step-by-step instructions
- Hands-on practice
- Guaranteed to work
- Minimal explanation
How-To Guide (Task-Oriented)
Goal: Solve a specific problem Example: "How to Add Authentication to Your API"- Assumes basic knowledge
- Focuses on one task
- Multiple approaches possible
- Problem-focused
Reference (Information-Oriented)
Goal: Describe the machinery Example: "API Authentication Methods Reference"- Technical description
- Complete and accurate
- Structured for lookup
- No teaching
Explanation (Understanding-Oriented)
Goal: Clarify and illuminate Example: "Understanding OAuth 2.0 Flow"- Conceptual discussion
- Provides context
- Alternative approaches
- Background knowledge
Tutorial Structure in X402
Standard Tutorial Template
# [Tutorial Title]: [Specific Outcome]
Direct Answer
[One sentence: What the learner will build/accomplish]
What You'll Build
[Brief description of the end result with screenshot/demo if possible]
Learning Objectives:
- Objective 1
- Objective 2
- Objective 3
Time Required: [Realistic estimate]
Prerequisites
Knowledge:
- Prerequisite skill 1
- Prerequisite skill 2
Tools:
- Tool 1 (version)
- Tool 2 (version)
Setup:
- Setup requirement 1
- Setup requirement 2
Steps
Step 1: [Action Verb] [What]
[Explanation of what we're doing and why]
[language]
Code or commands here
Expected Output:
Expected result here
Checkpoint: [How to verify this step worked]
Step 2: [Action Verb] [What]
[Continue pattern...]
Verification
Test your completed project:
- [ ] Check 1
- [ ] Check 2
- [ ] Check 3
What You Learned
- Skill 1
- Skill 2
- Skill 3
Next Steps
Continue learning:
- [Next tutorial in sequence]
- [Related advanced topic]
- [Different approach to try]
Troubleshooting
Issue 1: [Common Problem]
Symptom: [What learner sees]
Solution: [How to fix]
Complete Code
[Full working code available for reference]
Practical Example: Complete Tutorial
Here's a full tutorial following X402 structure:
# Build a Task API with Node.js and Express
Direct Answer
Build a working REST API for task management with Node.js and Express, including CRUD operations and data persistence, in 30 minutes.
What You'll Build
A RESTful API with these features:
- Create, read, update, and delete tasks
- In-memory data storage
- JSON responses
- Error handling
- Input validation
API Endpoints:
GET /tasks - List all tasks
POST /tasks - Create a task
GET /tasks/:id - Get a specific task
PUT /tasks/:id - Update a task
DELETE /tasks/:id - Delete a task
Time Required: 30 minutes
Prerequisites
Knowledge:
- Basic JavaScript syntax
- Understanding of HTTP methods (GET, POST, PUT, DELETE)
- Familiarity with JSON
Tools:
- Node.js 18+ installed (download)
- Text editor (VS Code, Sublime, etc.)
- Terminal/command line
- cURL or Postman (for testing)
Verify Prerequisites:
bash
node --version # Should show v18.0.0 or higher
npm --version # Should show 9.0.0 or higher
Steps
Step 1: Initialize Your Project
Create a new directory and initialize npm:
bash
mkdir task-api
cd task-api
npm init -y
Expected Output:json
{
"name": "task-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
...
}
Checkpoint: You should see a package.json file in your directory.
Step 2: Install Express
Install Express framework:
bash
npm install express
Expected Output:
added 57 packages, and audited 58 packages in 2s
Checkpoint: Check package.json - you should see Express in dependencies.
Step 3: Create the Server
Create index.js with basic server setup:
javascript
// index.js
const express = require('express');
const app = express();
const PORT = 3000;
// Middleware to parse JSON app.use(express.json());
// In-memory data store let tasks = [ { id: 1, title: 'Learn Node.js', completed: false }, { id: 2, title: 'Build an API', completed: false } ];
let nextId = 3;
// Test endpoint app.get('/', (req, res) => { res.json({ message: 'Task API is running' }); });
// Start server
app.listen(PORT, () => {
console.log(Server running on http://localhost:${PORT});
});
Run the server:bash
node index.js
Expected Output:
Server running on http://localhost:3000
Checkpoint: Open http://localhost:3000 in your browser. You should see:json
{"message": "Task API is running"}
Step 4: Implement GET All Tasks
Add the endpoint to list all tasks:
javascript
// Add after the test endpoint
app.get('/tasks', (req, res) => {
res.json({
success: true,
count: tasks.length,
data: tasks
});
});
Test with cURL:bash
curl http://localhost:3000/tasks
Expected Output:json
{
"success": true,
"count": 2,
"data": [
{ "id": 1, "title": "Learn Node.js", "completed": false },
{ "id": 2, "title": "Build an API", "completed": false }
]
}
Checkpoint: You should see both sample tasks returned.
Step 5: Implement POST Create Task
Add the endpoint to create a new task:
javascript
app.post('/tasks', (req, res) => {
// Validate input
if (!req.body.title) {
return res.status(400).json({
success: false,
error: 'Title is required'
});
}
// Create new task const newTask = { id: nextId++, title: req.body.title, completed: req.body.completed || false };
tasks.push(newTask);
res.status(201).json({ success: true, data: newTask }); });
Test with cURL:bash
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"title": "Write documentation"}'
Expected Output:json
{
"success": true,
"data": {
"id": 3,
"title": "Write documentation",
"completed": false
}
}
Checkpoint: The new task should have id: 3 and appear in the GET /tasks list.
Step 6: Implement GET Single Task
Add endpoint to get a specific task:
javascript
app.get('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const task = tasks.find(t => t.id === taskId);
if (!task) { return res.status(404).json({ success: false, error: 'Task not found' }); }
res.json({ success: true, data: task }); });
Test:bash
curl http://localhost:3000/tasks/1
Expected Output:json
{
"success": true,
"data": {
"id": 1,
"title": "Learn Node.js",
"completed": false
}
}
Checkpoint: Request for task ID 1 should return that task. Request for ID 999 should return 404.
Step 7: Implement PUT Update Task
Add endpoint to update a task:
javascript
app.put('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex === -1) { return res.status(404).json({ success: false, error: 'Task not found' }); }
// Update task tasks[taskIndex] = { ...tasks[taskIndex], title: req.body.title || tasks[taskIndex].title, completed: req.body.completed !== undefined ? req.body.completed : tasks[taskIndex].completed };
res.json({ success: true, data: tasks[taskIndex] }); });
Test:bash
curl -X PUT http://localhost:3000/tasks/1 \
-H "Content-Type: application/json" \
-d '{"completed": true}'
Expected Output:json
{
"success": true,
"data": {
"id": 1,
"title": "Learn Node.js",
"completed": true
}
}
Checkpoint: Task 1 should now show completed: true.
Step 8: Implement DELETE Task
Add endpoint to delete a task:
javascript
app.delete('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex === -1) { return res.status(404).json({ success: false, error: 'Task not found' }); }
const deletedTask = tasks.splice(taskIndex, 1)[0];
res.json({ success: true, data: deletedTask }); });
Test:bash
curl -X DELETE http://localhost:3000/tasks/2
Expected Output:json
{
"success": true,
"data": {
"id": 2,
"title": "Build an API",
"completed": false
}
}
Checkpoint: Task 2 should be removed. GET /tasks should only show 2 tasks now.
Verification
Test your complete API:
- [ ] GET /tasks returns all tasks
- [ ] POST /tasks creates a new task
- [ ] POST /tasks without title returns 400 error
- [ ] GET /tasks/:id returns specific task
- [ ] GET /tasks/999 returns 404 error
- [ ] PUT /tasks/:id updates a task
- [ ] DELETE /tasks/:id removes a task
- [ ] Server runs without errors
Full Test Script:
bash
Create a task
curl -X POST http://localhost:3000/tasks \ -H "Content-Type: application/json" \ -d '{"title": "Test task"}'List all tasks
curl http://localhost:3000/tasksUpdate task 1
curl -X PUT http://localhost:3000/tasks/1 \ -H "Content-Type: application/json" \ -d '{"completed": true}'Delete task 1
curl -X DELETE http://localhost:3000/tasks/1Verify deletion
curl http://localhost:3000/tasks
What You Learned
In this tutorial, you learned:
- Setting up a Node.js project with Express
- Creating RESTful API endpoints
- Handling different HTTP methods (GET, POST, PUT, DELETE)
- Validating user input
- Returning appropriate status codes
- Managing in-memory data
- Error handling in Express
Next Steps
Enhance your API:
- Add Database Persistence with MongoDB
- Add User Authentication with JWT
- Deploy Your API to Production
- Add API Documentation with Swagger
Troubleshooting
Server won't start: "Port 3000 already in use"
Symptom: Error when running node index.js
Error: listen EADDRINUSE: address already in use :::3000
Solution: Either kill the process using port 3000 or use a different port:bash
Find and kill process on port 3000
lsof -ti:3000 | xargs kill -9Or change PORT in index.js
const PORT = 3001;
"Cannot find module 'express'"
Symptom: Error when starting server
Error: Cannot find module 'express'
Solution: Install dependencies:bash
npm install
POST request returns 400 "Title is required"
Symptom: Creating a task fails even with title provided
Solution: Ensure you're sending JSON and setting Content-Type header:
bash
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"title": "My task"}'
Changes to code don't take effect
Symptom: Code changes not reflected in API behavior
Solution: Restart the server:
- Press Ctrl+C to stop server
- Run
node index.js again
- Or use nodemon for auto-restart:
bash
npm install -D nodemon
npx nodemon index.js
Complete Code
Final index.js:
javascript
const express = require('express');
const app = express();
const PORT = 3000;
app.use(express.json());
let tasks = [ { id: 1, title: 'Learn Node.js', completed: false }, { id: 2, title: 'Build an API', completed: false } ];
let nextId = 3;
// Root endpoint app.get('/', (req, res) => { res.json({ message: 'Task API is running' }); });
// Get all tasks app.get('/tasks', (req, res) => { res.json({ success: true, count: tasks.length, data: tasks }); });
// Get single task app.get('/tasks/:id', (req, res) => { const taskId = parseInt(req.params.id); const task = tasks.find(t => t.id === taskId);
if (!task) { return res.status(404).json({ success: false, error: 'Task not found' }); }
res.json({ success: true, data: task }); });
// Create task app.post('/tasks', (req, res) => { if (!req.body.title) { return res.status(400).json({ success: false, error: 'Title is required' }); }
const newTask = { id: nextId++, title: req.body.title, completed: req.body.completed || false };
tasks.push(newTask);
res.status(201).json({ success: true, data: newTask }); });
// Update task app.put('/tasks/:id', (req, res) => { const taskId = parseInt(req.params.id); const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex === -1) { return res.status(404).json({ success: false, error: 'Task not found' }); }
tasks[taskIndex] = { ...tasks[taskIndex], title: req.body.title || tasks[taskIndex].title, completed: req.body.completed !== undefined ? req.body.completed : tasks[taskIndex].completed };
res.json({ success: true, data: tasks[taskIndex] }); });
// Delete task app.delete('/tasks/:id', (req, res) => { const taskId = parseInt(req.params.id); const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex === -1) { return res.status(404).json({ success: false, error: 'Task not found' }); }
const deletedTask = tasks.splice(taskIndex, 1)[0];
res.json({ success: true, data: deletedTask }); });
app.listen(PORT, () => {
console.log(Server running on http://localhost:${PORT});
});
package.json:json
{
"name": "task-api",
"version": "1.0.0",
"description": "Simple task management API",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"keywords": ["api", "rest", "express"],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
Best Practices for Writing Tutorials in X402
1. One Clear Learning Goal
❌ Bad: "Learn Node.js, Express, MongoDB, Docker, and Kubernetes" ✅ Good: "Build a REST API with Node.js and Express"
Keep tutorials focused on one primary learning objective.
2. Test Every Step
Before publishing:
- [ ] Follow the tutorial from scratch yourself
- [ ] Test on a fresh environment
- [ ] Verify all code examples work
- [ ] Check all links and references
- [ ] Have someone else test it
3. Show Expected Output
After every step, show what learners should see:
Expected Output:
Server running on http://localhost:3000
This builds confidence and helps catch errors early.
4. Provide Checkpoints
At critical steps, include verification:
Checkpoint: Run npm test. All 5 tests should pass.
5. Explain the Why
Don't just tell learners what to type:
❌ "Add this code:" ✅ "We need middleware to parse JSON request bodies, so add:"
6. Handle Errors Proactively
Include troubleshooting for predictable issues:
- Port already in use
- Missing dependencies
- Version conflicts
- Permission errors
7. Organize Tutorials in Learning Paths
Structure batches as progressive learning:
batch-tutorials-001/ # Beginner
├── intro-to-node.md
├── first-express-app.md
└── rest-api-basics.md
batch-tutorials-002/ # Intermediate
├── add-database.md
├── authentication.md
└── error-handling.md
batch-tutorials-003/ # Advanced
├── microservices.md
├── testing-strategies.md
└── deployment.md
8. Include Time Estimates
Be realistic about time required:
- Include setup time
- Account for troubleshooting
- Test with beginners
- Add 50% buffer
9. Link to Next Steps
End each tutorial with clear progression:
## Next Steps
Continue this learning path:
- [Add Database Persistence] (next in sequence)
- [Add Authentication] (parallel skill)
- [Deploy to Production] (advanced application)
10. Provide Complete Working Code
Always include:
- Full final code
- Downloadable repository
- Working demo (if possible)
Tutorial Quality Checklist
Before marking a tutorial complete:
Content
- [ ] Single clear learning goal stated upfront
- [ ] Prerequisites explicitly listed
- [ ] Realistic time estimate included
- [ ] Every step tested and working
- [ ] Expected output shown for each step
- [ ] Checkpoints at critical stages
- [ ] Troubleshooting section included
- [ ] Complete working code provided
Structure
- [ ] Follows X402 tutorial template
- [ ] Steps numbered and sequential
- [ ] Code blocks have language specified
- [ ] Commands clearly distinguished from code
- [ ] Related tutorials linked
Quality
- [ ] Tested on fresh environment
- [ ] Tested by someone else
- [ ] All links working
- [ ] Screenshots/diagrams clear
- [ ] No assumed knowledge beyond prerequisites
- [ ] Consistent voice and tone
AEO Optimization
- [ ] Direct Answer section present
- [ ] Scannable with headers
- [ ] Code blocks formatted correctly
- [ ] Related questions addressed
- [ ] Quality standards met
Organizing Tutorials in Batches
By Skill Level
batch-tutorials-beginner/
batch-tutorials-intermediate/
batch-tutorials-advanced/
By Technology
batch-tutorials-nodejs/
batch-tutorials-python/
batch-tutorials-docker/
By Learning Path
batch-tutorials-web-dev-01/ # HTML/CSS basics
batch-tutorials-web-dev-02/ # JavaScript fundamentals
batch-tutorials-web-dev-03/ # React basics
batch-tutorials-web-dev-04/ # Full-stack project
By Time Commitment
batch-tutorials-quick/ # 5-15 minutes
batch-tutorials-standard/ # 30-60 minutes
batch-tutorials-project/ # 2+ hours
Related Questions
How long should a tutorial be? Aim for 30-60 minutes for most tutorials. Longer tutorials should be split into a series. Shorter quick-start tutorials (5-15 min) are great for beginners.
Should tutorials explain concepts or just give steps? Tutorials focus on doing. Give brief context ("we need this because...") but save deep explanations for concept guides. Link to explanation docs for curious learners.
How do I keep tutorials up to date? Test tutorials quarterly, especially for fast-moving technologies. Use version pinning in prerequisites. Add "Last tested" date to metadata.
Can I combine multiple topics in one tutorial? Only if they're tightly coupled for a single outcome (e.g., "Deploy with Docker" combines Docker + deployment). Otherwise, create separate focused tutorials.
How do I handle different operating systems? Either write OS-specific tutorials or include OS-specific sections with tabs/conditionals. Always test on the platforms you document.
Quality Standards
- [x] Follows AEO format with Direct Answer
- [x] Includes complete tutorial template
- [x] Contains full working example (Task API)
- [x] Provides step-by-step verification
- [x] Documents best practices and quality checklist
- [x] Explains tutorial organization strategies
- [x] Includes troubleshooting guidance
- [x] Ready for production
Start Building with X402
Get our free X402 Implementation Starter Kit with ready-to-use templates, code examples, and best practices.
What is included:
- Quick-start implementation templates
- API integration examples
- Configuration best practices guide