Skip to main content
POST
/
api
/
tasks
Create Task
curl --request POST \
  --url https://api.example.com/api/tasks \
  --header 'Content-Type: application/json' \
  --data '
{
  "title": "<string>",
  "description": "<string>",
  "completed": true,
  "categoryId": "<string>"
}
'
{
  "_id": "<string>",
  "title": "<string>",
  "description": "<string>",
  "completed": true,
  "categoryId": "<string>",
  "createdAt": "<string>",
  "updatedAt": "<string>",
  "finishedAt": "<string>"
}

Endpoint

POST /api/tasks
Creates a new task in the system. The API automatically generates a UUID, sets the creation timestamp, and assigns default values for optional fields.

Request Body

title
string
required
The task title.Validation:
  • Minimum length: 3 characters
  • Maximum length: 25 characters
  • Automatically trimmed
Example: "Complete API documentation"
description
string
Optional detailed description of the task.Validation:
  • Maximum length: 25 characters
  • Automatically trimmed
Example: "Write comprehensive docs"
completed
boolean
default:"false"
Initial completion status of the task.Default: falseNote: If set to true, the finishedAt timestamp will be automatically set.Example: true
categoryId
string
default:"uncategorized"
The UUID of the category to assign this task to.Default: "uncategorized" (if not provided or empty string)Validation: No format validation on input, but should be a valid TaskCategory UUIDExample: "550e8400-e29b-41d4-a716-446655440000"

Response

Returns the newly created task object with all auto-generated fields.
_id
string
Auto-generated unique identifier (UUID v4).
title
string
The task title from the request.
description
string
The task description from the request (if provided).
completed
boolean
The completion status from the request or default value.
categoryId
string
The category ID from the request or "uncategorized".
createdAt
string
Auto-generated ISO 8601 timestamp of creation.
updatedAt
string
Not set on creation (only appears after first update).
finishedAt
string
Auto-generated ISO 8601 timestamp if completed is true, otherwise not present.

Status Codes

  • 201 Created - Task successfully created
  • 400 Bad Request - Validation failed (invalid or missing required fields)

Examples

curl -X POST http://localhost:3000/api/tasks \
  -H "Content-Type: application/json" \
  -d '{"title":"Complete documentation"}'

Request Examples

{
  "title": "Complete documentation"
}

Response Examples

{
  "_id": "d4c3b2a1-0f1e-4d3c-9b8a-7c6b5a4d3e2f",
  "title": "Write API documentation",
  "description": "Create comprehensive docs",
  "completed": false,
  "categoryId": "550e8400-e29b-41d4-a716-446655440000",
  "createdAt": "2026-03-11T12:00:00.000Z"
}

Validation Rules

All validation is performed server-side using Zod schemas. Invalid requests will return detailed error messages.
FieldRequiredTypeMinMaxDefault
titlestring325-
descriptionstring-25-
completedboolean--false
categoryIdstring--“uncategorized”

Usage Notes

Auto-Generated Fields: Never include _id, createdAt, updatedAt, or finishedAt in your request body. These are managed automatically by the API.
Creating Completed Tasks: If you’re importing historical data or creating tasks that are already done, set completed: true in your request. The API will automatically set the finishedAt timestamp to match createdAt.
Category Assignment: The API does not validate whether the categoryId you provide actually exists. Ensure you’re using valid category UUIDs from the /api/taskCategories endpoint.

Common Patterns

Create Task in Existing Category

// First, get or create a category
const categoryResponse = await fetch('http://localhost:3000/api/taskCategories', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Work' })
});
const category = await categoryResponse.json();

// Then create task in that category
const taskResponse = await fetch('http://localhost:3000/api/tasks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'Review code',
    categoryId: category._id
  })
});
const task = await taskResponse.json();

Bulk Create Tasks

const tasksToCreate = [
  { title: 'Task 1', description: 'First task' },
  { title: 'Task 2', description: 'Second task' },
  { title: 'Task 3', description: 'Third task' }
];

const createdTasks = await Promise.all(
  tasksToCreate.map(async (taskData) => {
    const response = await fetch('http://localhost:3000/api/tasks', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(taskData)
    });
    return response.json();
  })
);

console.log(`Created ${createdTasks.length} tasks`);

Build docs developers (and LLMs) love