Real-World Examples

Build a Todo API

Step-by-step guide to creating a complete CRUD API for a todo list application with authentication.

What You'll Build

Features

  • • Create, read, update, delete todos
  • • Mark todos as complete/incomplete
  • • Filter by status (all, active, completed)
  • • User authentication with API tokens
  • • Pagination for large lists

What You'll Learn

  • • RESTful API design principles
  • • HTTP methods and status codes
  • • Request/response data structures
  • • Authentication and authorization
  • • Error handling patterns

Time Required

⏱️ Approximately 30-45 minutes

Step 1: Create Your Project

Set Up a New Project
1

Navigate to Dashboard

Go to the main dashboard and click "New Project"

2

Name Your Project

Enter a descriptive name

Project Name: Todo API
3

Add Description

Optional but recommended

Description: A RESTful API for managing todo items
4

Create Project

Click "Create" and note your project slug

✓ Your project slug will look like proj_abc123xyz. You'll use this in all your API URLs.

Step 2: Define the Todo Schema

Create Your Data Structure

Navigate to your project's Endpoints tab and create a new endpoint /todos. Use this schema:

{
  "id": "{{datatype.uuid}}",
  "userId": "{{datatype.number(1, 100)}}",
  "title": "{{lorem.words(3)}}",
  "description": "{{lorem.sentence}}",
  "completed": "{{datatype.boolean}}",
  "priority": "{{helpers.arrayElement(['low', 'medium', 'high'])}}",
  "dueDate": "{{date.future}}",
  "createdAt": "{{date.past}}",
  "updatedAt": "{{date.recent}}"
}

Schema Breakdown

FieldTypeDescription
idUUIDUnique identifier for the todo
userIdNumberID of user who owns the todo
titleStringShort todo title (3 words)
descriptionStringDetailed description
completedBooleanCompletion status
priorityEnumlow, medium, or high
dueDateDateWhen the todo is due
createdAtDateWhen todo was created
updatedAtDateLast update timestamp

💡 Tip: Set the record count to 20 for testing. You can increase it later.

Step 3: Configure CRUD Endpoints

GETGet All Todos

Endpoint:

GET /api/proj_abc123/todos

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 10)
completedbooleanFilter by completion status
prioritystringFilter by priority level

Example Request

GET /api/proj_abc123/todos?page=1&limit=10&completed=false

Response (200 OK)

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "userId": 42,
      "title": "Buy groceries",
      "description": "Get milk, eggs, and bread from the store",
      "completed": false,
      "priority": "high",
      "dueDate": "2024-02-15T10:00:00Z",
      "createdAt": "2024-01-10T08:30:00Z",
      "updatedAt": "2024-01-12T14:22:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 20,
    "totalPages": 2
  }
}
GETGet Single Todo

Endpoint:

GET /api/proj_abc123/todos/:id

Example Request

GET /api/proj_abc123/todos/550e8400-e29b-41d4-a716-446655440000

Response (200 OK)

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "userId": 42,
  "title": "Buy groceries",
  "description": "Get milk, eggs, and bread from the store",
  "completed": false,
  "priority": "high",
  "dueDate": "2024-02-15T10:00:00Z",
  "createdAt": "2024-01-10T08:30:00Z",
  "updatedAt": "2024-01-12T14:22:00Z"
}

Response (404 Not Found)

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Todo not found"
  }
}
POSTCreate New Todo

Endpoint:

POST /api/proj_abc123/todos

Request Body

{
  "title": "Finish project documentation",
  "description": "Complete API docs and user guide",
  "priority": "high",
  "dueDate": "2024-02-20T17:00:00Z"
}

Response (201 Created)

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "userId": 42,
  "title": "Finish project documentation",
  "description": "Complete API docs and user guide",
  "completed": false,
  "priority": "high",
  "dueDate": "2024-02-20T17:00:00Z",
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:00:00Z"
}

Note: The id, userId, completed,createdAt, and updatedAt fields are automatically generated.

PUTUpdate Todo (Full)

Endpoint:

PUT /api/proj_abc123/todos/:id

Request Body (All fields required)

{
  "title": "Finish project documentation (Updated)",
  "description": "Complete API docs, user guide, and examples",
  "completed": true,
  "priority": "medium",
  "dueDate": "2024-02-22T17:00:00Z"
}

Response (200 OK)

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "userId": 42,
  "title": "Finish project documentation (Updated)",
  "description": "Complete API docs, user guide, and examples",
  "completed": true,
  "priority": "medium",
  "dueDate": "2024-02-22T17:00:00Z",
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-16T14:30:00Z"
}
PATCHUpdate Todo (Partial)

Endpoint:

PATCH /api/proj_abc123/todos/:id

Request Body (Only fields to update)

{
  "completed": true
}

Common Use Case: Toggle Completion

// Mark as complete
PATCH /api/proj_abc123/todos/660e8400-e29b-41d4-a716-446655440001
{ "completed": true }

// Mark as incomplete
PATCH /api/proj_abc123/todos/660e8400-e29b-41d4-a716-446655440001
{ "completed": false }

Response (200 OK)

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "userId": 42,
  "title": "Finish project documentation (Updated)",
  "description": "Complete API docs, user guide, and examples",
  "completed": true,
  "priority": "medium",
  "dueDate": "2024-02-22T17:00:00Z",
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-16T15:45:00Z"
}
DELETEDelete Todo

Endpoint:

DELETE /api/proj_abc123/todos/:id

Example Request

DELETE /api/proj_abc123/todos/660e8400-e29b-41d4-a716-446655440001

Response (204 No Content)

// No response body
// HTTP Status: 204 No Content

Response (404 Not Found)

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Todo not found"
  }
}

Step 4: Add Authentication

Secure Your API
1

Generate API Token

Go to Profile → API Tokens → Create New Token

Token Name: Todo App Development
2

Enable Authentication

In Project Settings → Security

  • • Toggle "Require Authentication" ON
  • • Select which endpoints require auth (all or specific)
  • • Save changes
3

Include Token in Requests

// Add Authorization header
GET /api/proj_abc123/todos
Authorization: Bearer your_token_here

// cURL example
curl -H "Authorization: Bearer your_token_here" \
  http://localhost:3000/api/proj_abc123/todos

// JavaScript fetch
fetch('/api/proj_abc123/todos', {
  headers: {
    'Authorization': 'Bearer your_token_here'
  }
})

⚠️ Security: Never commit API tokens to version control. Use environment variables in production.

Step 5: Test Your API

Using the Built-in API Tester
1

Open API Tester

Navigate to Project → API Tester tab

2

Test GET All Todos

Select: GET

/todos

Click "Send" → Verify 200 OK response with todo list

3

Test POST Create Todo

Select: POST

/todos

Body:

{
  "title": "Test todo",
  "priority": "high"
}

Click "Send" → Verify 201 Created with new todo

4

Test PATCH Update Todo

Copy an ID from GET response, then PATCH with {"completed": true}

5

Check Logs

Go to Logs tab to see all your test requests with timestamps and response times

Step 6: Integrate with Frontend

React Example
import { useState, useEffect } from 'react';
import { CodeBlock } from '@/app/components/CodeBlock';

const API_URL = 'http://localhost:3000/api/proj_abc123';
const API_TOKEN = process.env.REACT_APP_API_TOKEN;

function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [loading, setLoading] = useState(true);

  // Fetch all todos
  useEffect(() => {
    fetchTodos();
  }, []);

  const fetchTodos = async () => {
    try {
      const response = await fetch(`${API_URL}/todos`, {
        headers: {
          'Authorization': `Bearer ${API_TOKEN}`
        }
      });
      const result = await response.json();
      setTodos(result.data);
    } catch (error) {
      console.error('Error fetching todos:', error);
    } finally {
      setLoading(false);
    }
  };

  // Create new todo
  const createTodo = async (title, priority = 'medium') => {
    try {
      const response = await fetch(`${API_URL}/todos`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${API_TOKEN}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ title, priority })
      });
      const newTodo = await response.json();
      setTodos([...todos, newTodo]);
    } catch (error) {
      console.error('Error creating todo:', error);
    }
  };

  // Toggle todo completion
  const toggleTodo = async (id, completed) => {
    try {
      await fetch(`${API_URL}/todos/${id}`, {
        method: 'PATCH',
        headers: {
          'Authorization': `Bearer ${API_TOKEN}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ completed: !completed })
      });
      setTodos(todos.map(todo => 
        todo.id === id ? { ...todo, completed: !completed } : todo
      ));
    } catch (error) {
      console.error('Error updating todo:', error);
    }
  };

  // Delete todo
  const deleteTodo = async (id) => {
    try {
      await fetch(`${API_URL}/todos/${id}`, {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${API_TOKEN}`
        }
      });
      setTodos(todos.filter(todo => todo.id !== id));
    } catch (error) {
      console.error('Error deleting todo:', error);
    }
  };

  if (loading) return <div>Loading...</div>;

  return (
    <div className="todo-app">
      <h1>My Todos</h1>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id, todo.completed)}
            />
            <span style={{ 
              textDecoration: todo.completed ? 'line-through' : 'none' 
            }}>
              {todo.title}
            </span>
            <button onClick={() => deleteTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>
      <button onClick={() => createTodo('New Task', 'medium')}>
        Add Todo
      </button>
    </div>
  );
}

export default TodoApp;

Next Steps & Enhancements

Add More Features

• Add categories/tags

• Implement search

• Add sorting options

• Create subtasks

• Add file attachments

Improve Security

• Add rate limiting

• Implement user roles

• Add input validation

• Enable CORS restrictions

• Add request logging

Optimize Performance

• Enable caching

• Add database indexing

• Implement lazy loading

• Use pagination

• Compress responses

Documentation

• Generate OpenAPI spec

• Add API examples

• Create user guide

• Document error codes

• Add code samples

Congratulations! 🎉

You've successfully built a complete Todo API with:

Full CRUD operations (Create, Read, Update, Delete)
RESTful endpoint structure
Proper HTTP methods and status codes
Authentication with API tokens
Pagination and filtering
Frontend integration example

Continue learning with more tutorials or explore advanced features!