Skip to main content

Overview

DayCopilot implements automatic access control to ensure data security and privacy. All data records are scoped to the owning user and those who have active share permissions.
Access control is automatic and transparent. As an API integrator, you don’t need to filter by user ID manually - this is handled for you.

How Access Control Works

Automatic Data Scoping

When you make API requests, you only see data you have permission to access:
// ✅ Automatic filtering
async function getTasks() {
  const response = await fetch('/api/v1/tasks', {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  // Returns only tasks you own or have been shared with you
}
Benefits:
  • Impossible to access other users’ data
  • No manual filtering needed
  • Security enforced automatically
  • Works consistently across all queries

Authentication Flow

Data Access Rules

Your Own Data

You have full access to all resources you create:
# You can see all your tasks
GET /api/v1/tasks
# Returns all tasks you created

# You can access your specific task
GET /api/v1/tasks/your-task-id
# Returns 200 OK

# You cannot access another user's task
GET /api/v1/tasks/other-user-task-id
# Returns 404 Not Found (for security)
When you attempt to access a resource that doesn’t exist or you don’t have permission to access, you’ll receive a 404 error (not 403) for security reasons.

Shared Resources

When someone shares a context with you, you automatically gain access to its contents:
# User A shares context with User B
POST /api/v1/contexts/project-uuid/share
{
  "user_email": "userB@example.com",
  "permission": "write"
}

# User B can now see tasks in that context
GET /api/v1/tasks?context_id=project-uuid
# Returns tasks, even though User B isn't the owner

Permission Levels

DayCopilot supports three permission levels for shared contexts:
PermissionRead Tasks/EventsCreate Tasks/EventsUpdate Tasks/EventsDelete Tasks/Events
read
write
admin

Read Permission

Users with read permission can:
  • View all tasks and events in the shared context
  • See task details and event information
  • View comments and activity
They cannot:
  • Create new tasks or events
  • Modify existing tasks or events
  • Delete anything

Write Permission

Users with write permission can:
  • Everything included in read permission
  • Create new tasks and events in the context
  • Update existing tasks and events
  • Add comments
They cannot:
  • Delete tasks or events
  • Change context sharing settings
  • Remove the context

Admin Permission

Users with admin permission have full control:
  • Everything included in write permission
  • Delete tasks and events
  • Manage context sharing settings
  • Remove collaborators
  • Delete the context

Sharing & Collaboration

Context Sharing

When you share a context, collaborators get access to all items within it:
# Share a context
POST /api/v1/contexts/context-uuid/share
{
  "user_email": "colleague@example.com",
  "permission": "write"
}

# Response
{
  "context_id": "context-uuid",
  "shared_with": "colleague@example.com",
  "permission": "write",
  "shared_at": "2025-11-02T12:00:00Z"
}
What gets shared:
  • All tasks in the context
  • All events in the context
  • Ability to add new items (if permission allows)
  • Activity history

Task Assignment vs. Sharing

Assigning a task to someone does NOT automatically give them access. The task must be in a shared context for the assignee to see it.
# Assign task to another user
POST /api/v1/tasks/task-uuid/assign
{
  "user_email": "colleague@example.com"
}

# Colleague receives notification, but...
# They can only access if task is in a shared context
To give access to an assigned task:
  1. Create a shared context
  2. Add the task to that context
  3. Share the context with the assignee

Event Attendees

Adding someone as an event attendee automatically gives them access to that specific event:
# Add attendee to event
POST /api/v1/events/event-uuid/attendees
{
  "user_email": "attendee@example.com",
  "rsvp_status": "pending"
}

# Attendee can now read the event
GET /api/v1/events/event-uuid
# Works for attendee (returns 200 OK)

API Behavior

Creating Resources

You can only create resources for yourself:
# ✅ This works
POST /api/v1/tasks
{
  "title": "My task",
  "context_id": "my-context-uuid"
}
# user_id automatically set to your ID

# ❌ This fails - cannot specify another user
POST /api/v1/tasks
{
  "title": "Task for someone else",
  "user_id": "other-user-uuid"
}
# Returns 403 Forbidden

Querying with Filters

All queries automatically respect access control:
# This query automatically filters to your accessible tasks
GET /api/v1/tasks?status=pending

# This also respects access control
GET /api/v1/tasks?context_id=shared-context-uuid
# Returns tasks you have access to in this context

# You cannot bypass access control
GET /api/v1/tasks?user_id=other-user-uuid
# Ignored - you still only see your own data

Updating Resources

You can only update resources you own or have write/admin permission to:
# ✅ Update your own task
PUT /api/v1/tasks/your-task-uuid
{
  "status": "completed"
}
# Returns 200 OK

# ✅ Update task in shared context (with write permission)
PUT /api/v1/tasks/shared-task-uuid
{
  "status": "in_progress"
}
# Returns 200 OK

# ❌ Update task you don't have access to
PUT /api/v1/tasks/other-user-task-uuid
{
  "status": "completed"
}
# Returns 404 Not Found

Deleting Resources

You can only delete resources you own or have admin permission to:
# ✅ Delete your own task
DELETE /api/v1/tasks/your-task-uuid
# Returns 204 No Content

# ❌ Delete task in shared context with write permission
DELETE /api/v1/tasks/shared-task-uuid
# Returns 403 Forbidden (need admin permission)

# ✅ Delete task in shared context with admin permission
DELETE /api/v1/tasks/shared-task-uuid
# Returns 204 No Content

Security Guarantees

Guarantee: You can only access your own data and data explicitly shared with you.Even if you guess or enumerate resource IDs, you cannot access resources you don’t have permission to view.
Guarantee: All queries are automatically scoped to your user account.You don’t need to add user ID filters - attempting to access other users’ data will be blocked automatically.
Guarantee: Permission levels are strictly enforced.Read-only access prevents modifications, write access prevents deletions, and only admin access allows full control.
Guarantee: Access denials return 404 (not 403) for non-existent resources.This prevents information disclosure about the existence of resources you don’t have access to.

Best Practices

The API automatically scopes data to the authenticated user. Adding user_id filters is redundant and may cause confusion.
// ❌ Redundant filtering
GET /api/v1/tasks?user_id=${currentUserId}

// ✅ Let the API handle it
GET /api/v1/tasks
Always use contexts and sharing features for collaboration. Don’t try to work around access control.
// ✅ Proper collaboration
1. Create shared context
2. Add tasks to context
3. Share context with team members
When you receive a 404 error, it could mean the resource doesn’t exist OR you don’t have access. Handle both cases gracefully.
try {
  const task = await getTask(taskId);
} catch (error) {
  if (error.status === 404) {
    // Could be missing or forbidden
    console.log('Task not found or access denied');
  }
}
Always test integrations with multiple user accounts to verify access control works correctly and data is properly isolated.

Debugging Access Issues

Common Problems

Problem: Can’t see tasks in a shared context Solution:
  1. Verify the context was shared with you: GET /api/v1/contexts/context-uuid/collaborators
  2. Check that tasks are in the correct context: GET /api/v1/tasks?context_id=context-uuid
  3. Confirm your permission level allows the action you’re trying to perform

Problem: Getting 404 for a resource you think should exist Solution:
  1. Verify you’re using the correct resource ID
  2. Check if the resource is in a context shared with you
  3. Confirm you have the right permission level (read/write/admin)
  4. Validate your JWT token is current and valid

Problem: Can’t create tasks in a shared context Solution:
  1. Verify you have at least write permission: GET /api/v1/contexts/context-uuid
  2. Ensure you’re specifying the correct context_id in the request body
  3. Check that the context still exists and hasn’t been deleted

Next Steps