Overview
Projects provide a way to categorize and organize time entries within a company. Each project has a name, optional description, and color for visual identification.
Key Features
- Company-scoped: Each project belongs to a single company
- Active/Inactive Status: Control which projects are available for new time entries
- Color Coding: Visual identification with hex color codes
- Search Support: Find projects by name
- Time Entry Tracking: Projects track how many time entries reference them
Authentication
All endpoints require:
- Valid JWT authentication token
- Platform admin role (checked via middleware)
Create Project
curl -X POST https://api.example.com/projects \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Platform API",
"description": "Core API development and maintenance",
"color": "#10B981",
"isActive": true
}'
{
"success": true,
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Platform API",
"description": "Core API development and maintenance",
"color": "#10B981",
"isActive": true,
"createdAt": "2026-03-04T15:30:00.000Z",
"updatedAt": "2026-03-04T15:30:00.000Z",
"createdBy": "440e8400-e29b-41d4-a716-446655440000",
"updatedBy": "440e8400-e29b-41d4-a716-446655440000"
}
}
Request Body
UUID of the company this project belongs to
Project name (2-150 characters)
Detailed description (max 2000 characters, optional)
Hex color code for visual identification (e.g., “#10B981”)Must match pattern: ^#[0-9A-Fa-f]{6}$
Whether the project is active and available for new time entries
Response Fields
All request fields plus:
id: Generated UUID
createdAt, updatedAt: Timestamps
createdBy, updatedBy: User IDs who created/updated the project
List Projects
curl -X GET "https://api.example.com/projects?companyId=550e8400-e29b-41d4-a716-446655440000&page=1&limit=50&isActive=true&search=API" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"data": [
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Platform API",
"description": "Core API development and maintenance",
"color": "#10B981",
"isActive": true,
"createdAt": "2026-03-04T15:30:00.000Z",
"updatedAt": "2026-03-04T15:30:00.000Z"
},
{
"id": "661e8400-e29b-41d4-a716-446655440000",
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Mobile API",
"description": "Mobile application backend services",
"color": "#3B82F6",
"isActive": true,
"createdAt": "2026-03-03T10:00:00.000Z",
"updatedAt": "2026-03-03T10:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 2,
"totalPages": 1
}
}
Query Parameters
Filter by active status
true: Only active projects
false: Only inactive projects
- Omit: All projects
Search projects by name (case-insensitive partial match)
Get Project by ID
curl -X GET https://api.example.com/projects/660e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Platform API",
"description": "Core API development and maintenance",
"color": "#10B981",
"isActive": true,
"createdAt": "2026-03-04T15:30:00.000Z",
"updatedAt": "2026-03-04T15:30:00.000Z",
"createdBy": "440e8400-e29b-41d4-a716-446655440000",
"updatedBy": "440e8400-e29b-41d4-a716-446655440000"
}
}
Path Parameters
Update Project
curl -X PATCH https://api.example.com/projects/660e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Platform API v2",
"color": "#6366F1",
"isActive": false
}'
{
"success": true,
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"companyId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Platform API v2",
"description": "Core API development and maintenance",
"color": "#6366F1",
"isActive": false,
"updatedAt": "2026-03-04T16:00:00.000Z",
"updatedBy": "440e8400-e29b-41d4-a716-446655440000"
}
}
Path Parameters
UUID of the project to update
Request Body
All fields are optional. Only provided fields will be updated.
Update project name (2-150 characters)
Update description (max 2000 characters)
Update hex color code (must match ^#[0-9A-Fa-f]{6}$)
Update active statusMarking a project as inactive (isActive: false) does not affect existing time entries linked to it, but prevents the project from being selected for new entries in UI applications.
Delete Project
curl -X DELETE https://api.example.com/projects/660e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"message": "Project deleted successfully"
}
Path Parameters
UUID of the project to delete
When a project is deleted:
- All time entries linked to this project will have their
projectId set to null (cascade: SetNull)
- This is a permanent operation and cannot be undone
- Consider marking the project as inactive instead if you want to preserve the relationship
Project Colors
Default Color
The default project color is #10B981 (emerald green).
Recommended Colors
For visual consistency, consider using these Tailwind-inspired colors:
| Color Name | Hex Code | Preview |
|---|
| Emerald | #10B981 | Sample |
| Blue | #3B82F6 | Sample |
| Indigo | #6366F1 | Sample |
| Purple | #8B5CF6 | Sample |
| Pink | #EC4899 | Sample |
| Orange | #F97316 | Sample |
Best Practices
Project Organization
- Use Descriptive Names: Make project names clear and specific (e.g., “Mobile App Backend” vs. “Project 1”)
- Set Colors Strategically: Use different colors for different types of projects or clients
- Archive Instead of Delete: Set
isActive: false instead of deleting projects to maintain time entry history
- Add Descriptions: Use the description field to document project scope, client information, or billing details
Active Status Management
Example: Archiving a completed project
{
"isActive": false,
"description": "Core API development and maintenance [ARCHIVED 2026-03-04: Project completed]"
}
Search and Filtering
Finding all active projects with in the name
curl "https://api.example.com/projects?companyId=550e8400&isActive=true&search=API"
Common Use Cases
1. Setting up projects for a new company
const projects = [
{ name: "Internal Development", color: "#10B981" },
{ name: "Client Work", color: "#3B82F6" },
{ name: "Maintenance", color: "#6366F1" },
{ name: "Training", color: "#F59E0B" },
];
for (const project of projects) {
await createProject({
companyId: company.id,
...project,
isActive: true
});
}
2. Deactivating old projects at year-end
const oldProjects = await listProjects({
companyId: company.id,
isActive: true
});
for (const project of oldProjects.data) {
if (project.lastUsed < '2025-12-31') {
await updateProject(project.id, { isActive: false });
}
}
3. Bulk color update for client projects
const clientProjects = await listProjects({
companyId: company.id,
search: "Client -"
});
for (const project of clientProjects.data) {
await updateProject(project.id, { color: "#3B82F6" });
}