Skip to content

feat: Add support for /api/v1/activities endpoint in TypeScript SDK #312

@kyzzen

Description

@kyzzen

Add support for /api/v1/activities endpoint in TypeScript SDK

Enhancement description

Add a getActivities() method to the TodoistApi class that exposes the /api/v1/activities endpoint from the REST API v1. This endpoint provides activity logs and audit trail functionality, but is not currently available in the @doist/todoist-api-typescript SDK.

The implementation would include:

  • A new getActivities() method on the TodoistApi class
  • TypeScript interfaces for GetActivitiesArgs and GetActivitiesResponse
  • Full type definitions for ActivityEvent objects
  • Support for pagination via cursor
  • Filtering by object type, event type, project, and user

The problem it solves

Currently, developers using the TypeScript SDK cannot access activity data, which prevents them from:

  1. Building productivity analytics - Cannot analyze task completion patterns, track time spent on projects, or identify workflow bottlenecks
  2. Creating audit trails - Cannot monitor who made changes in shared projects, essential for team accountability and compliance
  3. Generating automated reports - Cannot create daily standups, weekly summaries, or productivity reports
  4. Implementing recovery features - Cannot understand what changed before issues occurred or implement undo functionality
  5. Tracking task evolution - Cannot see how tasks changed over time (original vs current due dates, reassignments, etc.)

This limitation forces developers to choose between:

  • Using raw HTTP calls (losing type safety, error handling, and authentication management)
  • Abandoning these features entirely
  • Switching to a different task management platform

Alternatives

Current Workarounds

  1. Raw HTTP Calls
async function getActivities(token: string, params: any) {
    const queryString = new URLSearchParams(params).toString()
    const response = await fetch(`https://api.todoist.com/rest/v1/activities?${queryString}`, {
        headers: { 'Authorization': `Bearer ${token}` }
    })
    return response.json()
}

Drawbacks: No type safety, manual error handling, token management complexity

  1. Extend SDK Class (Possible workaround)
class ExtendedTodoistApi extends TodoistApi {
    async getActivities(params: any): Promise<any> {
        // Custom implementation using internal HTTP client
    }
}

Drawbacks: Brittle, may break with SDK updates, requires maintenance

  1. Use Completed Tasks Endpoint (Partial workaround)
await api.getCompletedTasksByCompletionDate({ since: '2024-01-01' })

Drawbacks: Only shows completions, not updates/additions/deletions

Use case / screenshots

Use Case 1: Daily Standup Generation

// With the proposed enhancement
const activities = await api.getActivities({
    event_type: 'completed',
    limit: 50,
    cursor: null
})

const yesterdayCompleted = activities.events.filter(event => 
    isYesterday(event.event_date)
)
console.log(`Yesterday I completed: ${yesterdayCompleted.map(e => e.extra_data.content).join(', ')}`)

Use Case 2: Project Audit Trail

// Track all changes to a specific project
const projectActivities = await api.getActivities({
    object_type: 'project',
    object_id: 'project_123',
    limit: 100
})

// Generate audit report
projectActivities.events.forEach(event => {
    console.log(`${event.event_date}: User ${event.initiator_id} ${event.event_type} - ${event.extra_data.content}`)
})

Use Case 3: Productivity Analytics

// Analyze task completion patterns
const activities = await api.getActivities({
    event_type: 'completed',
    parent_project_id: 'work_project'
})

const completionsByHour = activities.events.reduce((acc, event) => {
    const hour = new Date(event.event_date).getHours()
    acc[hour] = (acc[hour] || 0) + 1
    return acc
}, {})

console.log('Most productive hours:', completionsByHour)

API Endpoint Documentation

The endpoint is already fully documented:

Additional information

Suggested Implementation

// Add to TodoistApi class
async getActivities(args?: GetActivitiesArgs): Promise<GetActivitiesResponse> {
    return this.restApiClient.get('/activities', args);
}

// Type definitions
export interface GetActivitiesArgs {
    object_type?: 'project' | 'item' | 'note';
    object_id?: string;
    event_type?: string;
    parent_project_id?: string;
    parent_item_id?: string;
    initiator_id?: string;
    limit?: number;
    cursor?: string | null;
}

export interface GetActivitiesResponse {
    events: ActivityEvent[];
    next_cursor: string | null;
}

export interface ActivityEvent {
    id: number;
    object_type: string;
    object_id: string;
    event_type: string;
    event_date: string;
    parent_project_id?: string;
    parent_item_id?: string;
    initiator_id?: string;
    extra_data?: {
        content?: string;
        project_name?: string;
        last_content?: string;
        due_date?: string;
        last_due_date?: string;
        client?: string;
        [key: string]: any;
    };
}

Impact and Benefits

  • Backwards compatible - Only adds new functionality
  • Consistent with SDK patterns - Follows existing method signatures
  • Type-safe - Full TypeScript support
  • Enables MCP servers - Critical for AI assistants and integrations
  • Already proven - Endpoint is stable and documented in API v1

Who Benefits

  • MCP (Model Context Protocol) server developers
  • Business intelligence and reporting tool builders
  • Team collaboration feature developers
  • Productivity tracking application creators
  • Todoist power users who need automation

This feature has been requested by the community developing the Todoist MCP server, where a placeholder implementation has already been created awaiting SDK support.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions