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
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
}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
}
]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
}
]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
}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
}Shares a habit with your connected partner.
Request Body:
{
"habitId": "habit_abc123"
}Response (200 OK):
{
"success": true
}Permanently deletes a habit.
Response (200 OK):
{
"success": true
}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:
- Call this endpoint once per day when a user completes their habit
- The endpoint automatically handles streak calculation based on the last check-in time
- If more than 24 hours have passed since the last check-in (and it's not the same day), the streak resets to 1
- If the user tries to check in multiple times in one day, the request will be rejected
- 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
}