Habits API Documentation

A comprehensive guide to implementing habit tracking and sharing features

Overview

The Habits API enables tracking, sharing, and managing personal habits. It supports both "build" habits (positive behaviors to cultivate) and "break" habits (behaviors to eliminate). The API provides functionality for creating individual or bulk habits, tracking streaks, checking in, and sharing habits with partners.

Key Features

  • Create and manage personal habits
  • Track streaks and check-in history
  • Bulk creation of multiple habits
  • Share habits with partners
  • Filtering habits by type (build/break)
  • Set and manage daily reminders for habits

API Documentation

Base URL: api.wecompleteapp.com/api/users/user/:userId/habits

POST api.wecompleteapp.com/api/users/user/:userId/habitsCreate a Habit

Creates a new habit for tracking.

Request Body:

{
  "action": "create",
  "title": "Daily Exercise",
  "type": "build",
  "frequency": "daily",
  "description": "30 minutes of physical activity",
  "icon": "🏃‍♂️",
  "sharedWith": ["user_123456"],
  "interests": ["health", "fitness"],
  "reminderTime": 510
}

Response (200 OK):

{
  "id": "habit_abc123",
  "userId": "user_789xyz",
  "title": "Daily Exercise",
  "description": "30 minutes of physical activity",
  "type": "build",
  "frequency": "daily",
  "streak": 0,
  "longestStreak": 0,
  "lastCheckedIn": 0,
  "icon": "🏃‍♂️",
  "startDate": 1686067200000,
  "sharedWith": ["user_123456"],
  "weeklyCheckIns": [],
  "monthlyCheckIns": [],
  "isActive": true,
  "createdAt": 1686067200000,
  "reminderTime": 510,
  "reminderEnabled": true
}
POST api.wecompleteapp.com/api/users/user/:userId/habitsCreate Multiple Habits

Creates multiple habits in a single request.

Request Body:

{
  "action": "createBulk",
  "habits": [
    {
      "title": "Exercise daily",
      "type": "build",
      "frequency": "daily",
      "description": "Do at least 30 minutes of exercise",
      "reminderTime": 510
    },
    {
      "title": "Stop using social media before bed",
      "type": "break",
      "frequency": "daily",
      "icon": "📱",
      "reminderTime": 1320
    },
    {
      "title": "Read 10 pages",
      "type": "build",
      "frequency": "daily"
    }
  ]
}

Response (200 OK):

[
  {
    "id": "habit_abc123",
    "userId": "user_789xyz",
    "title": "Exercise daily",
    "description": "Do at least 30 minutes of exercise",
    "type": "build",
    "frequency": "daily",
    "streak": 0,
    "longestStreak": 0,
    "lastCheckedIn": 0,
    "startDate": 1686067200000,
    "weeklyCheckIns": [],
    "monthlyCheckIns": [],
    "isActive": true,
    "createdAt": 1686067200000,
    "reminderTime": 510,
    "reminderEnabled": true
  },
  {
    "id": "habit_def456",
    "userId": "user_789xyz",
    "title": "Stop using social media before bed",
    "type": "break",
    "frequency": "daily",
    "icon": "📱",
    "streak": 0,
    "longestStreak": 0,
    "lastCheckedIn": 0,
    "startDate": 1686067200000,
    "weeklyCheckIns": [],
    "monthlyCheckIns": [],
    "isActive": true,
    "createdAt": 1686067200000,
    "reminderTime": 1320,
    "reminderEnabled": true
  },
  {
    "id": "habit_ghi789",
    "userId": "user_789xyz",
    "title": "Read 10 pages",
    "type": "build",
    "frequency": "daily",
    "streak": 0,
    "longestStreak": 0,
    "lastCheckedIn": 0,
    "startDate": 1686067200000,
    "weeklyCheckIns": [],
    "monthlyCheckIns": [],
    "isActive": true,
    "createdAt": 1686067200000,
    "reminderEnabled": false
  }
]
GET api.wecompleteapp.com/api/users/user/:userId/habitsGet User Habits

Retrieves all habits for a user.

Query Parameters (optional):

  • type - Filter by habit type ("build" or "break")

Response (200 OK):

[
  {
    "id": "habit_abc123",
    "userId": "user_789xyz",
    "title": "Daily Exercise",
    "description": "30 minutes of physical activity",
    "type": "build",
    "frequency": "daily",
    "streak": 3,
    "longestStreak": 5,
    "lastCheckedIn": 1686240000000,
    "icon": "🏃‍♂️",
    "startDate": 1686067200000,
    "sharedWith": ["user_123456"],
    "weeklyCheckIns": [1686153600000, 1686240000000],
    "monthlyCheckIns": [1686153600000, 1686240000000],
    "isActive": true,
    "createdAt": 1686067200000
  },
  {
    "id": "habit_def456",
    "userId": "user_789xyz",
    "title": "Stop Smoking",
    "type": "break",
    "frequency": "daily",
    "streak": 7,
    "longestStreak": 7,
    "lastCheckedIn": 1686240000000,
    "icon": "🚭",
    "startDate": 1685980800000,
    "sharedWith": [],
    "weeklyCheckIns": [1686067200000, 1686153600000, 1686240000000],
    "monthlyCheckIns": [1686067200000, 1686153600000, 1686240000000],
    "isActive": true,
    "createdAt": 1685980800000
  }
]
PATCH api.wecompleteapp.com/api/users/user/:userId/habits/{habitId}Update Habit or Check-in

Updates habit details or records a check-in.

Request Body (Update):

{
  "title": "Daily Exercise and Stretching",
  "description": "30 minutes of physical activity plus stretching",
  "icon": "🏋️‍♂️",
  "reminderTime": 450,
  "reminderEnabled": true
}

Request Body (Check-in):

{
  "checkIn": true
}

Response (200 OK):

{
  "id": "habit_abc123",
  "userId": "user_789xyz",
  "title": "Daily Exercise and Stretching",
  "description": "30 minutes of physical activity plus stretching",
  "type": "build",
  "frequency": "daily",
  "streak": 4,
  "longestStreak": 5,
  "lastCheckedIn": 1686326400000,
  "icon": "🏋️‍♂️",
  "startDate": 1686067200000,
  "sharedWith": ["user_123456"],
  "weeklyCheckIns": [1686153600000, 1686240000000, 1686326400000],
  "monthlyCheckIns": [1686153600000, 1686240000000, 1686326400000],
  "isActive": true,
  "createdAt": 1686067200000,
  "reminderTime": 450,
  "reminderEnabled": true
}
PATCH api.wecompleteapp.com/api/users/user/:userId/habits/{habitId}/reminderUpdate Habit Reminder

Updates or toggles a habit's reminder settings.

Request Body:

{
  "reminderTime": 480,
  "enabled": true
}

Response (200 OK):

{
  "id": "habit_abc123",
  "userId": "user_789xyz",
  "title": "Daily Exercise",
  "description": "30 minutes of physical activity",
  "type": "build",
  "frequency": "daily",
  "streak": 3,
  "longestStreak": 5,
  "lastCheckedIn": 1686240000000,
  "icon": "🏃‍♂️",
  "startDate": 1686067200000,
  "sharedWith": ["user_123456"],
  "weeklyCheckIns": [1686153600000, 1686240000000],
  "monthlyCheckIns": [1686153600000, 1686240000000],
  "isActive": true,
  "createdAt": 1686067200000,
  "reminderTime": 480,
  "reminderEnabled": true
}
POST api.wecompleteapp.com/api/users/user/:userId/habits/partnerShare Habit with Partner

Shares a habit with your connected partner.

Request Body:

{
  "habitId": "habit_abc123"
}

Response (200 OK):

{
  "success": true
}
DELETE api.wecompleteapp.com/api/users/user/:userId/habits/{habitId}Delete a Habit

Permanently deletes a habit.

Response (200 OK):

{
  "success": true
}
POST api.wecompleteapp.com/api/users/user/:userId/habits/{habitId}/streakUpdate Habit Streak

Updates a habit's streak with streak protection logic. This endpoint handles the complex logic of streak tracking, including:

  • Incrementing streaks when checked in daily
  • Resetting streaks when a day is missed
  • Preventing multiple check-ins on the same day
  • Tracking longest streak records
  • Maintaining weekly and monthly check-in history

How to Use:

  1. Call this endpoint once per day when a user completes their habit
  2. The endpoint automatically handles streak calculation based on the last check-in time
  3. If more than 24 hours have passed since the last check-in (and it's not the same day), the streak resets to 1
  4. If the user tries to check in multiple times in one day, the request will be rejected
  5. The response includes the updated habit with the new streak value and check-in history

Implementation Example:

// Example React component function
async function checkInHabit(userId, habitId) {
  try {
    const response = await fetch(
      `/api/users/user/${userId}/habits/${habitId}/streak`, 
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ checkIn: true })
      }
    );
    
    const data = await response.json();
    
    if (data.success) {
      // Update UI with new streak information
      updateStreakDisplay(data.habit.streak);
      showSuccessMessage(data.message);
    } else {
      // Handle already checked in case
      showInfoMessage(data.message);
    }
    
    return data;
  } catch (error) {
    console.error("Error updating streak:", error);
    showErrorMessage("Failed to update streak");
  }
}

Request Body:

{
  "checkIn": true
}

Response (200 OK):

{
  "success": true,
  "message": "Streak updated successfully",
  "habit": {
    "id": "habit_12345",
    "userId": "user_123",
    "title": "Morning Meditation",
    "description": "10 minutes of mindfulness meditation",
    "frequency": "daily",
    "streak": 5,
    "longestStreak": 10,
    "lastCheckedIn": 1642441200000,
    "type": "build",
    "icon": "meditation",
    "startDate": 1642441200000,
    "weeklyCheckIns": [1642441200000, 1642527600000, 1642614000000, 1642700400000, 1642786800000],
    "monthlyCheckIns": [1642441200000, 1642527600000, 1642614000000, 1642700400000, 1642786800000],
    "isActive": true,
    "createdAt": "2023.01.17. 12.00",
    "checkedToday": true
  }
}

Error Responses:

// Already checked in today
{
  "success": false,
  "message": "Already checked in today",
  "habit": { ... habit data ... }
}

// Habit not found
{
  "error": "Habit not found",
  "code": "not_found"
}

// Unauthorized
{
  "error": "Unauthorized to update this habit",
  "code": "unauthorized"
}

Streak Tracking Logic:

  • First check-in: Sets streak to 1
  • Consecutive daily check-ins: Increments streak by 1
  • Missed day: Resets streak to 1
  • Longest streak: Automatically updated when current streak exceeds previous record
  • Weekly history: Maintains rolling 7-day check-in timestamps
  • Monthly history: Maintains rolling 30-day check-in timestamps

Data Models

Habit

interface Habit {
  // Core Properties
  id: string;
  userId: string;
  title: string;
  description?: string;
  type: 'build' | 'break';
  frequency: 'daily' | 'weekly' | 'monthly';
  
  // Tracking Properties
  streak: number;
  longestStreak: number;
  lastCheckedIn: number;
  weeklyCheckIns: number[];
  monthlyCheckIns: number[];
  
  // Configuration
  icon?: string;
  sharedWith: string[];
  isActive: boolean;
  startDate: number;
  interests: string[];
  
  // Reminder Settings
  reminderTime?: number; // Time of day in minutes from midnight (e.g., 8:30am = 510)
  reminderEnabled: boolean;
  
  // System Metadata
  createdAt: number;
}

SharedHabitView

interface SharedHabitView {
  id: string;
  title: string;
  currentStreak: number;
  lastCheckedIn: number;
  partnerProgress: {
    streak: number;
    lastSync: number;
  };
}

Reminder

interface Reminder {
  id: string;
  userId: string;
  entityType: string; // "habit", "event", etc.
  entityId: string;
  time: number; // Time of day in minutes from midnight
  frequency: 'daily' | 'weekly' | 'monthly' | 'once';
  daysOfWeek?: number[]; // For weekly reminders: [0,1,2,3,4,5,6] where 0=Sunday
  date?: number; // For one-time or monthly reminders
  isActive: boolean;
  message?: string;
  lastTriggered?: number;
  createdAt: number;
}

Error Handling

400 - Validation Error

{
  "error": "Invalid habit type",
  "code": "validation_error",
  "details": {
    "path": "type",
    "received": "build-break",
    "expected": ["build", "break"]
  }
}

404 - Not Found

{
  "error": "Habit not found",
  "code": "not_found",
  "habitId": "habit_123456"
}

401 - Unauthorized

{
  "error": "Not authorized to access this habit",
  "code": "unauthorized"
}

429 - Rate Limited

{
  "error": "Too many check-ins",
  "code": "rate_limit",
  "retryAfter": 3600
}