Todo List Fake API for Testing CRUD Operations
A simple and developer-friendly Todo API for practicing REST API workflows like GET, POST, PUT, PATCH, and DELETE. Use it to learn API basics, test apps, build demos, or practice frontend integration with realistic Todo data.
Best for
Students, frontend developers, API beginners, and app prototyping.
Supports
cURL, Fetch, Axios, Python, Ruby on Rails, and Next.js.
Base URL
https://shrimo.com/fake-api/todosBase URL
https://shrimo.com/fake-api/todosWhat is this API for?
Quick Test
https://shrimo.com/fake-api/todos to retrieve a list of Todo items and test your API flow.Quick start example
Start with a simple GET request to fetch all Todo items. This is the easiest way to confirm the API is working in your app or test environment.
fetch("https://shrimo.com/fake-api/todos")
.then((res) => res.json())
.then((data) => console.log(data));Todo object schema
Each Todo item includes fields such as title, description, due date, priority, status, and tags. This realistic structure makes it useful for practice apps, dashboards, forms, and table-based UI examples.
{
"id": "672f0dee814c297b16f90093",
"title": "Learn JavaScript",
"description": "Complete JavaScript basics",
"dueDate": "2026-04-20T00:00:00.000Z",
"priority": "High",
"status": "Not Started",
"tags": ["JavaScript", "Learning"],
"createdAt": "2026-04-15T10:00:00.000Z",
"updatedAt": "2026-04-15T10:00:00.000Z"
}API reference
/todosGet all Todo items. Use this for list pages, dashboards, and table views.
/todos/:idGet one Todo by ID. Use this for a detail page or edit form.
/todosCreate a new Todo item. Useful for forms and create actions.
/todos/:idReplace an existing Todo with a full updated version.
/todos/:idUpdate one or more fields on an existing Todo.
/todos/:idDelete a Todo item by ID.
/todosGet all todos
What it does: Use GET when you want to read or fetch data.
When to use it: Use this when you want to display all Todo items in a list, table, or dashboard.
Request Body
No request body needed for this method.
Example Response
{
"success": true,
"count": 2,
"data": [
{
"id": "672f0dee814c297b16f90093",
"title": "Learn JavaScript",
"description": "Complete JavaScript basics",
"dueDate": "2026-04-20T00:00:00.000Z",
"priority": "High",
"status": "Not Started",
"tags": ["JavaScript", "Learning"]
},
{
"id": "672f0dee814c297b16f90094",
"title": "Build Todo App",
"description": "Create a practice project",
"dueDate": "2026-04-22T00:00:00.000Z",
"priority": "Medium",
"status": "In Progress",
"tags": ["Project"]
}
]
}GET /todos examples by language
cURL
curl -X GET "https://shrimo.com/fake-api/todos"JavaScript (Fetch)
const getTodos = async () => {
const response = await fetch("https://shrimo.com/fake-api/todos");
const data = await response.json();
console.log(data);
};
getTodos();JavaScript (Axios)
import axios from "axios";
const getTodos = async () => {
try {
const response = await axios.get("https://shrimo.com/fake-api/todos");
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
getTodos();Python
import requests
response = requests.get("https://shrimo.com/fake-api/todos")
data = response.json()
print(data)Ruby on Rails
require "net/http"
require "uri"
require "json"
uri = URI.parse("https://shrimo.com/fake-api/todos")
response = Net::HTTP.get_response(uri)
if response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)
else
puts "Error: #{response.code}"
endNext.js
export default async function TodoPage() {
const res = await fetch("https://shrimo.com/fake-api/todos", {
cache: "no-store",
});
const result = await res.json();
return (
<div>
<h1>All Todos</h1>
{result.data.map((todo) => (
<div key={todo.id}>
<h2>{todo.title}</h2>
<p>{todo.description}</p>
</div>
))}
</div>
);
}/todos/:idGet one todo by ID
What it does: Use GET with an ID when you want only one item.
When to use it: Use this when you want to open one Todo item and show its details.
Request Body
No request body needed for this method.
Example Response
{
"success": true,
"count": 1,
"data": {
"id": "672f0dee814c297b16f90093",
"title": "Learn JavaScript",
"description": "Complete JavaScript basics",
"dueDate": "2026-04-20T00:00:00.000Z",
"priority": "High",
"status": "Not Started",
"tags": ["JavaScript", "Learning"]
}
}GET /todos/:id examples by language
cURL
curl -X GET "https://shrimo.com/fake-api/todos/672f0dee814c297b16f90093"JavaScript (Fetch)
const getTodoById = async (id) => {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`);
const data = await response.json();
console.log(data);
};
getTodoById("672f0dee814c297b16f90093");JavaScript (Axios)
import axios from "axios";
const getTodoById = async (id) => {
try {
const response = await axios.get(`https://shrimo.com/fake-api/todos/${id}`);
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
getTodoById("672f0dee814c297b16f90093");Python
import requests
todo_id = "672f0dee814c297b16f90093"
response = requests.get(f"https://shrimo.com/fake-api/todos/{todo_id}")
print(response.json())Ruby on Rails
require "net/http"
require "uri"
require "json"
todo_id = "672f0dee814c297b16f90093"
uri = URI.parse("https://shrimo.com/fake-api/todos/#{todo_id}")
response = Net::HTTP.get_response(uri)
if response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)
else
puts "Error: #{response.code}"
endNext.js
export default async function TodoDetailsPage() {
const res = await fetch("https://shrimo.com/fake-api/todos/672f0dee814c297b16f90093", {
cache: "no-store",
});
const result = await res.json();
const todo = result.data;
return (
<div>
<h1>{todo.title}</h1>
<p>{todo.description}</p>
<p>Status: {todo.status}</p>
</div>
);
}/todosCreate a new todo
What it does: Use POST when you want to create new data.
When to use it: Use this when a user submits a create form or adds a new task.
Request Body
{
"title": "Learn APIs",
"description": "Practice CRUD methods",
"dueDate": "2026-04-20",
"priority": "High",
"status": "Not Started",
"tags": ["API", "Practice"]
}Example Response
{
"success": true,
"message": "Todo added successfully.",
"data": {
"id": "672f0dee814c297b16f90093",
"title": "Learn APIs",
"description": "Practice CRUD methods",
"dueDate": "2026-04-20T00:00:00.000Z",
"priority": "High",
"status": "Not Started",
"tags": ["API", "Practice"]
}
}POST /todos examples by language
cURL
curl -X POST "https://shrimo.com/fake-api/todos" \
-H "Content-Type: application/json" \
-d '{
"title": "Learn APIs",
"description": "Practice CRUD methods",
"dueDate": "2026-04-20",
"priority": "High",
"status": "Not Started",
"tags": ["API", "Practice"]
}'JavaScript (Fetch)
const createTodo = async () => {
const response = await fetch("https://shrimo.com/fake-api/todos", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Learn APIs",
description: "Practice CRUD methods",
dueDate: "2026-04-20",
priority: "High",
status: "Not Started",
tags: ["API", "Practice"],
}),
});
const data = await response.json();
console.log(data);
};
createTodo();JavaScript (Axios)
import axios from "axios";
const createTodo = async () => {
try {
const response = await axios.post("https://shrimo.com/fake-api/todos", {
title: "Learn APIs",
description: "Practice CRUD methods",
dueDate: "2026-04-20",
priority: "High",
status: "Not Started",
tags: ["API", "Practice"],
});
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
createTodo();Python
import requests
payload = {
"title": "Learn APIs",
"description": "Practice CRUD methods",
"dueDate": "2026-04-20",
"priority": "High",
"status": "Not Started",
"tags": ["API", "Practice"]
}
response = requests.post("https://shrimo.com/fake-api/todos", json=payload)
print(response.json())Ruby on Rails
require "net/http"
require "uri"
require "json"
uri = URI.parse("https://shrimo.com/fake-api/todos")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, {
"Content-Type" => "application/json"
})
request.body = {
title: "Learn APIs",
description: "Practice CRUD methods",
dueDate: "2026-04-20",
priority: "High",
status: "Not Started",
tags: ["API", "Practice"]
}.to_json
response = http.request(request)
puts JSON.parse(response.body)Next.js
async function createTodo() {
const response = await fetch("https://shrimo.com/fake-api/todos", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Learn APIs",
description: "Practice CRUD methods",
dueDate: "2026-04-20",
priority: "High",
status: "Not Started",
tags: ["API", "Practice"],
}),
});
return response.json();
}/todos/:idReplace a todo with PUT
What it does: Use PUT when you want to update an existing item with a full new version.
When to use it: Use this when you want to replace most or all values of an existing Todo item.
Request Body
{
"title": "Learn APIs Better",
"description": "Practice GET, POST, PUT, PATCH and DELETE",
"dueDate": "2026-04-25",
"priority": "Critical",
"status": "In Progress",
"tags": ["API", "Study"]
}Example Response
{
"success": true,
"message": "Todo updated successfully.",
"data": {
"id": "672f0dee814c297b16f90093",
"title": "Learn APIs Better",
"description": "Practice GET, POST, PUT, PATCH and DELETE",
"dueDate": "2026-04-25T00:00:00.000Z",
"priority": "Critical",
"status": "In Progress",
"tags": ["API", "Study"]
}
}PUT /todos/:id examples by language
cURL
curl -X PUT "https://shrimo.com/fake-api/todos/672f0dee814c297b16f90093" \
-H "Content-Type: application/json" \
-d '{
"title": "Learn APIs Better",
"description": "Practice GET, POST, PUT, PATCH and DELETE",
"dueDate": "2026-04-25",
"priority": "Critical",
"status": "In Progress",
"tags": ["API", "Study"]
}'JavaScript (Fetch)
const updateTodo = async (id) => {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Learn APIs Better",
description: "Practice GET, POST, PUT, PATCH and DELETE",
dueDate: "2026-04-25",
priority: "Critical",
status: "In Progress",
tags: ["API", "Study"],
}),
});
const data = await response.json();
console.log(data);
};
updateTodo("672f0dee814c297b16f90093");JavaScript (Axios)
import axios from "axios";
const updateTodo = async (id) => {
try {
const response = await axios.put(`https://shrimo.com/fake-api/todos/${id}`, {
title: "Learn APIs Better",
description: "Practice GET, POST, PUT, PATCH and DELETE",
dueDate: "2026-04-25",
priority: "Critical",
status: "In Progress",
tags: ["API", "Study"],
});
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
updateTodo("672f0dee814c297b16f90093");Python
import requests
todo_id = "672f0dee814c297b16f90093"
payload = {
"title": "Learn APIs Better",
"description": "Practice GET, POST, PUT, PATCH and DELETE",
"dueDate": "2026-04-25",
"priority": "Critical",
"status": "In Progress",
"tags": ["API", "Study"]
}
response = requests.put(f"https://shrimo.com/fake-api/todos/{todo_id}", json=payload)
print(response.json())Ruby on Rails
require "net/http"
require "uri"
require "json"
todo_id = "672f0dee814c297b16f90093"
uri = URI.parse("https://shrimo.com/fake-api/todos/#{todo_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri.request_uri, {
"Content-Type" => "application/json"
})
request.body = {
title: "Learn APIs Better",
description: "Practice GET, POST, PUT, PATCH and DELETE",
dueDate: "2026-04-25",
priority: "Critical",
status: "In Progress",
tags: ["API", "Study"]
}.to_json
response = http.request(request)
puts JSON.parse(response.body)Next.js
async function updateTodo(id) {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Learn APIs Better",
description: "Practice GET, POST, PUT, PATCH and DELETE",
dueDate: "2026-04-25",
priority: "Critical",
status: "In Progress",
tags: ["API", "Study"],
}),
});
return response.json();
}/todos/:idPartially update a todo
What it does: Use PATCH when you want to change only one or two fields.
When to use it: Use this when you only want to update status, title, or another small part of the Todo item.
Request Body
{
"status": "Completed"
}Example Response
{
"success": true,
"message": "Todo patched successfully.",
"data": {
"id": "672f0dee814c297b16f90093",
"title": "Learn JavaScript",
"description": "Complete JavaScript basics",
"dueDate": "2026-04-20T00:00:00.000Z",
"priority": "High",
"status": "Completed",
"tags": ["JavaScript", "Learning"]
}
}PATCH /todos/:id examples by language
cURL
curl -X PATCH "https://shrimo.com/fake-api/todos/672f0dee814c297b16f90093" \
-H "Content-Type: application/json" \
-d '{
"status": "Completed"
}'JavaScript (Fetch)
const patchTodo = async (id) => {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "Completed",
}),
});
const data = await response.json();
console.log(data);
};
patchTodo("672f0dee814c297b16f90093");JavaScript (Axios)
import axios from "axios";
const patchTodo = async (id) => {
try {
const response = await axios.patch(`https://shrimo.com/fake-api/todos/${id}`, {
status: "Completed",
});
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
patchTodo("672f0dee814c297b16f90093");Python
import requests
todo_id = "672f0dee814c297b16f90093"
payload = {
"status": "Completed"
}
response = requests.patch(f"https://shrimo.com/fake-api/todos/{todo_id}", json=payload)
print(response.json())Ruby on Rails
require "net/http"
require "uri"
require "json"
todo_id = "672f0dee814c297b16f90093"
uri = URI.parse("https://shrimo.com/fake-api/todos/#{todo_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(uri.request_uri, {
"Content-Type" => "application/json"
})
request.body = {
status: "Completed"
}.to_json
response = http.request(request)
puts JSON.parse(response.body)Next.js
async function patchTodo(id) {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "Completed",
}),
});
return response.json();
}/todos/:idDelete a todo
What it does: Use DELETE when you want to remove data.
When to use it: Use this when a user clicks a delete button and you want to remove the Todo item permanently.
Request Body
No request body needed for this method.
Example Response
{
"success": true,
"message": "Todo deleted successfully."
}DELETE /todos/:id examples by language
cURL
curl -X DELETE "https://shrimo.com/fake-api/todos/672f0dee814c297b16f90093"JavaScript (Fetch)
const deleteTodo = async (id) => {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "DELETE",
});
const data = await response.json();
console.log(data);
};
deleteTodo("672f0dee814c297b16f90093");JavaScript (Axios)
import axios from "axios";
const deleteTodo = async (id) => {
try {
const response = await axios.delete(`https://shrimo.com/fake-api/todos/${id}`);
console.log(response.data);
} catch (error) {
console.error("Error:", error.message);
}
};
deleteTodo("672f0dee814c297b16f90093");Python
import requests
todo_id = "672f0dee814c297b16f90093"
response = requests.delete(f"https://shrimo.com/fake-api/todos/{todo_id}")
print(response.json())Ruby on Rails
require "net/http"
require "uri"
require "json"
todo_id = "672f0dee814c297b16f90093"
uri = URI.parse("https://shrimo.com/fake-api/todos/#{todo_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri.request_uri)
response = http.request(request)
puts JSON.parse(response.body)Next.js
async function deleteTodo(id) {
const response = await fetch(`https://shrimo.com/fake-api/todos/${id}`, {
method: "DELETE",
});
return response.json();
}Status codes made simple
200 OK
201 Created
400 Bad Request
404 Not Found
Best learning order
1. Start with GET /todos
2. Then try POST /todos
3. Then use GET /todos/:id
4. Then learn PUT and PATCH
5. Finally test DELETE /todos/:id
Frequently asked questions
What is a fake API?
A fake API is a sample or mock API used for testing, learning, prototyping, and frontend integration without depending on a live production backend.
Is this Todo API free to use?
Yes. This Todo API is designed for learning, testing, and developer practice.
Can I use this API with React or Next.js?
Yes. You can use this API with React, Next.js, JavaScript Fetch, Axios, Python requests, and other HTTP libraries.
What is the difference between PUT and PATCH?
PUT is generally used to replace the full resource with updated data, while PATCH is used to update only part of a resource, such as just the status field.
Related links
Need this for a real project?
We can help you turn this workflow into a production-ready system.
Tools are useful for quick work, learning, and testing. If you need the same idea inside a real website, dashboard, CRM, portal, API, or business workflow, our team can plan, design, and build it with proper user roles, validation, performance, and long-term support.
Want to learn this properly?
Learn practical web development with guided training.
If you are a student, fresher, or developer building your skills, explore training and internship options instead of only using the tool once.
Related tools
