API Reference

Tasks API

Create, manage, and complete tasks via the REST API.

The Tasks API allows programmatic management of habits, dailies, and to-dos.

Endpoints

MethodEndpointDescription
GET/api/tasksList all tasks
POST/api/tasksCreate a new task
GET/api/tasks/:idGet task by ID
PATCH/api/tasks/:idUpdate a task
DELETE/api/tasks/:idArchive a task
POST/api/tasks/:id/completeMark task as complete

Task Object

{
  id: string                    // UUID
  userId: string                // Owner UUID
  teamId: string | null         // Team UUID if shared task
  type: 'habit' | 'daily' | 'todo'
  title: string                 // Task name
  notes: string | null          // Optional description
  difficulty: 'trivial' | 'easy' | 'medium' | 'hard'
  tags: string[]                // Optional tags
  schedule: object | null       // For dailies: { days: [0-6] }
  isPositive: boolean           // For habits: true = positive
  streak: number                // Consecutive completions
  dueDate: string | null        // ISO date for todos
  archived: boolean             // If task is archived
  createdAt: string             // ISO timestamp
  updatedAt: string             // ISO timestamp
}

List Tasks

GET /api/tasks

Query Parameters:

ParameterTypeDescription
typestringFilter by type: habit, daily, todo
archivedbooleanInclude archived tasks (default: false)
teamIdstringFilter by team
sortstringSort field (default: -createdAt)
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)

Example Request:

curl "https://habito.ar/api/tasks?type=habit&archived=false" \
  -H "Authorization: Bearer hab_your_key"

Example Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "userId": "user-uuid",
      "teamId": null,
      "type": "habit",
      "title": "Morning workout",
      "notes": "30 minutes cardio + stretching",
      "difficulty": "medium",
      "tags": ["fitness", "morning"],
      "schedule": null,
      "isPositive": true,
      "streak": 15,
      "dueDate": null,
      "archived": false,
      "createdAt": "2024-01-01T10:00:00.000Z",
      "updatedAt": "2024-01-15T09:30:00.000Z"
    }
  ],
  "meta": {
    "total": 12,
    "page": 1,
    "perPage": 20
  }
}

Create Task

POST /api/tasks

Request Body:

FieldTypeRequiredDescription
typestringYeshabit, daily, or todo
titlestringYesTask name (max 200 chars)
notesstringNoDescription
difficultystringYestrivial, easy, medium, hard
tagsstringNoArray of tags
scheduleobjectConditionalRequired for dailies
isPositivebooleanConditionalRequired for habits
dueDatestringNoISO date for todos
teamIdstringNoCreate as team task

Example: Create Habit

curl -X POST https://habito.ar/api/tasks \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "habit",
    "title": "Drink 8 glasses of water",
    "difficulty": "easy",
    "isPositive": true,
    "tags": ["health"]
  }'

Example: Create Daily

curl -X POST https://habito.ar/api/tasks \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "daily",
    "title": "Gym workout",
    "difficulty": "medium",
    "schedule": {
      "days": [1, 3, 5]
    }
  }'

Schedule days: 0 = Sunday, 1 = Monday, ..., 6 = Saturday

Example: Create To-Do

curl -X POST https://habito.ar/api/tasks \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "todo",
    "title": "Buy birthday gift",
    "difficulty": "easy",
    "dueDate": "2024-03-15"
  }'

Success Response:

HTTP/1.1 201 Created

{
  "data": {
    "id": "new-task-uuid",
    "userId": "user-uuid",
    "type": "habit",
    "title": "Drink 8 glasses of water",
    "difficulty": "easy",
    "isPositive": true,
    "streak": 0,
    "archived": false,
    "createdAt": "2024-02-03T10:00:00.000Z",
    "updatedAt": "2024-02-03T10:00:00.000Z"
  }
}

Get Task

GET /api/tasks/:id

Example Request:

curl https://habito.ar/api/tasks/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer hab_your_key"

Success Response:

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userId": "user-uuid",
    "type": "habit",
    "title": "Morning workout",
    "notes": "30 minutes cardio",
    "difficulty": "medium",
    "tags": ["fitness"],
    "isPositive": true,
    "streak": 15,
    "archived": false,
    "createdAt": "2024-01-01T10:00:00.000Z",
    "updatedAt": "2024-01-15T09:30:00.000Z"
  }
}

Update Task

PATCH /api/tasks/:id

Updatable Fields:

  • title
  • notes
  • difficulty
  • tags
  • schedule (dailies only)
  • dueDate (todos only)
  • archived

Example Request:

curl -X PATCH https://habito.ar/api/tasks/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "difficulty": "hard",
    "tags": ["fitness", "morning", "essential"]
  }'

Success Response:

HTTP/1.1 200 OK

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "difficulty": "hard",
    "tags": ["fitness", "morning", "essential"],
    "updatedAt": "2024-02-03T11:00:00.000Z"
  }
}

Archive Task

DELETE /api/tasks/:id

Archives the task (soft delete). Archived tasks don't appear in default listings but are preserved for history.

Example Request:

curl -X DELETE https://habito.ar/api/tasks/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer hab_your_key"

Success Response:

HTTP/1.1 204 No Content

To restore: Use PATCH /api/tasks/:id with { "archived": false }

Complete Task

POST /api/tasks/:id/complete

Marks a task as complete for today. Awards XP based on difficulty and streak.

Example Request:

curl -X POST https://habito.ar/api/tasks/550e8400-e29b-41d4-a716-446655440000/complete \
  -H "Authorization: Bearer hab_your_key"

Success Response:

{
  "data": {
    "task": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "streak": 16,
      "updatedAt": "2024-02-03T12:00:00.000Z"
    },
    "xpEarned": 24,
    "newLevel": 8,
    "leveledUp": false
  }
}

Response Fields:

  • task: Updated task with new streak
  • xpEarned: XP awarded (includes streak bonus)
  • newLevel: Current user level after completion
  • leveledUp: true if user leveled up from this completion

Validation Errors

Missing Required Fields

HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Title is required",
    "details": {
      "field": "title",
      "rule": "required"
    }
  }
}

Invalid Field Values

HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid task type. Must be habit, daily, or todo",
    "details": {
      "field": "type",
      "value": "invalid",
      "allowed": ["habit", "daily", "todo"]
    }
  }
}

Schedule Required for Dailies

HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Schedule is required for daily tasks",
    "details": {
      "field": "schedule",
      "rule": "required_for_dailies"
    }
  }
}

Common Use Cases

Daily Sync Script

// Sync tasks to external system
const apiKey = process.env.HABITO_API_KEY

async function syncTasks() {
  const response = await fetch('https://habito.ar/api/tasks', {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  })

  const { data: tasks } = await response.json()

  for (const task of tasks) {
    await externalSystem.syncTask(task)
  }
}

syncTasks()

Automated Task Completion

// Complete tasks based on external triggers
async function completeTask(taskId) {
  const response = await fetch(
    `https://habito.ar/api/tasks/${taskId}/complete`,
    {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${process.env.HABITO_API_KEY}` }
    }
  )

  const { data } = await response.json()

  if (data.leveledUp) {
    console.log(`🎉 Leveled up to ${data.newLevel}!`)
  }

  console.log(`Earned ${data.xpEarned} XP`)
}

Bulk Task Creation

// Create multiple tasks from a template
const habitTemplates = [
  { title: 'Morning meditation', difficulty: 'easy' },
  { title: 'Exercise 30min', difficulty: 'medium' },
  { title: 'Read 1 chapter', difficulty: 'easy' },
  { title: 'No social media after 9pm', difficulty: 'hard' }
]

async function createHabits() {
  for (const template of habitTemplates) {
    await fetch('https://habito.ar/api/tasks', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        type: 'habit',
        isPositive: true,
        ...template
      })
    })
  }
}

Next Steps

Pro Tip: Use webhooks (coming soon) to receive real-time notifications when tasks are completed instead of polling the API.