Developer
News and Updates
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Object types
Object operations
User operations
Group operations
Task operations
Last updated May 28, 2026

scheduleOrUpdateTask

The scheduleOrUpdateTask method schedules a recurring root task that the platform invokes on a fixed cadence. Calling it again for the same (connectionId, taskId) updates the existing schedule rather than creating a new one, so it is safe to call from both the CREATED and UPDATED branches of onConnectionChange.

Method signature

1
2
scheduleOrUpdateTask(request: TaskScheduleRequest): Promise<TaskScheduleResponse>

Parameter: request

  • Type: TaskScheduleRequest
  • Required: Yes
  • Description: The schedule request, identifying the connection, the cadence, and the task to schedule.
1
2
{
  connectionId: string;            // The connection this task belongs to
  scheduleInterval: ScheduleInterval; // Cadence for the recurring invocation
  task: Task;                      // The task to schedule (taskType + taskId)
}

ScheduleInterval

1
2
{
  value: number;                   // Cadence (must be between 1 and 60 inclusive)
  timeUnit: 'minutes' | 'hours' | 'days';
}

scheduleInterval is the gap between consecutive invocations of the same root task; it is not aligned to wall-clock minutes or hours. If you need clock-aligned timing, gate the work yourself inside taskRunner.

Task

1
2
{
  taskType: ForgeTaskType;         // One of types.FORGE_TASK_TYPES (closed enum)
  taskId: string;                  // Stable UUID for this root task
}

ForgeTaskType is a closed enum exposed by the SDK. Use the types.FORGE_TASK_TYPES.* constants:

1
2
import { types } from '@forge/teamwork-graph';

types.FORGE_TASK_TYPES.USER_INGESTION_FULL;
types.FORGE_TASK_TYPES.USER_INGESTION_INCREMENTAL;
types.FORGE_TASK_TYPES.GROUP_INGESTION_FULL;
types.FORGE_TASK_TYPES.GROUP_INGESTION_INCREMENTAL;
types.FORGE_TASK_TYPES.ENTITY_INGESTION_FULL;
types.FORGE_TASK_TYPES.ENTITY_INGESTION_INCREMENTAL;
types.FORGE_TASK_TYPES.RELATIONSHIP_INGESTION_FULL;
types.FORGE_TASK_TYPES.RELATIONSHIP_INGESTION_INCREMENTAL;

Persist the same value on the TaskInfo you write to KVS and use it as the dispatch key inside taskRunner. See Task types.

Usage examples

Schedule a root ingestion task on a connection

1
2
import { graph, types } from '@forge/teamwork-graph';
import { v4 as uuid } from 'uuid';
import { kvs } from '@forge/kvs';

async function getOrCreateRootTaskId(connectionId: string, key: string): Promise<string> {
  const kvsKey = `rootTaskId:${connectionId}:${key}`;
  const existing = await kvs.get(kvsKey) as string | undefined;
  if (existing) return existing;
  const id = uuid();
  await kvs.set(kvsKey, id);
  return id;
}

export async function scheduleEntityIngestion(connectionId: string): Promise<void> {
  const taskId = await getOrCreateRootTaskId(connectionId, 'entity-ingestion');

  const response = await graph.scheduleOrUpdateTask({
    connectionId,
    scheduleInterval: { value: 5, timeUnit: 'minutes' },
    task: {
      taskType: types.FORGE_TASK_TYPES.ENTITY_INGESTION_INCREMENTAL,
      taskId,
    },
  });

  if (response.error) {
    console.error('Failed to schedule task:', response.error);
    return;
  }
  console.log(`Scheduled root task ${taskId} (${response.status}: ${response.message})`);
}

Schedule from onConnectionChange

1
2
export const onConnectionChange = async (request: OnConnectionChangeRequest) => {
  switch (request.action) {
    case 'CREATED':
    case 'UPDATED':
      await scheduleEntityIngestion(request.connectionId);
      break;
    case 'DELETED':
      // Drop your KVS state. The platform tears down the schedule itself.
      break;
  }
  return { success: true };
};

After a successful scheduleOrUpdateTask call, the first invocation typically fires within a few seconds, not at the next interval boundary. Subsequent invocations follow the configured cadence.

Request validation

The method validates the following:

  • connectionId: Required, must be a non-empty string.
  • scheduleInterval.value: Must be a number between 1 and 60 inclusive.
  • scheduleInterval.timeUnit: Must be one of 'minutes', 'hours', 'days'.
  • task.taskType: Required, non-empty, max 255 characters, and must be one of the values exposed by types.FORGE_TASK_TYPES.
  • task.taskId: Required, must be a valid UUID. See taskId must be a UUID.

Error handling

Error messageDescription
connectionId is requiredThe connectionId is missing or empty.
scheduleInterval.value must be between 1 and 60The scheduleInterval.value is outside the supported range.
scheduleInterval.timeUnit must be one of: minutes, hours, daysThe scheduleInterval.timeUnit is not a supported unit.
task.taskType is requiredThe task.taskType is missing or empty.
task.taskType must not exceed 255 charactersThe task.taskType is longer than the 255-character limit.
task.taskType must be one of: user_ingestion_full, user_ingestion_incremental, ...The task.taskType is not one of the values exposed by types.FORGE_TASK_TYPES.
task.taskId must be a valid UUID formatThe provided taskId is not a valid UUID. Use uuid() from the uuid package.

Response

The method returns a promise that resolves to a TaskScheduleResponse.

1
2
{
  status: string;          // Status string from the platform (e.g. "ACCEPTED")
  message: string;         // Human-readable status message
  taskId: string;          // The taskId that was scheduled (echoes input)
  error?: string;          // Error message if the request failed
  originalError?: unknown; // Original platform error object, when available
}

On success, the response carries status, message, and taskId. On failure, the SDK returns an object shaped like { error, originalError } (the success: false field is also set at runtime as a casting artifact). Branch on response.error to detect failures.

Type safety

The SDK provides type-safe request and response objects that ensure compile-time validation:

1
2
import { graph, types } from '@forge/teamwork-graph';

const request: types.TaskScheduleRequest = {
  connectionId: 'connection-id-123',
  scheduleInterval: { value: 5, timeUnit: 'minutes' },
  task: {
    taskType: types.FORGE_TASK_TYPES.ENTITY_INGESTION_INCREMENTAL,
    taskId: 'b3e8e1f4-3a12-4d2e-9a6f-12c4a9c8b1aa',
  },
};

const response: types.TaskScheduleResponse = await graph.scheduleOrUpdateTask(request);

if (response.error) {
  console.error('Failed to schedule task:', response.error);
} else {
  console.log(`Scheduled root task ${response.taskId} (${response.status})`);
}

The type system ensures:

  • task.taskType is constrained to the ForgeTaskType union exposed by types.FORGE_TASK_TYPES.
  • scheduleInterval.timeUnit is restricted to 'minutes' | 'hours' | 'days'.
  • request has the correct TaskScheduleRequest structure.
  • response is properly typed as TaskScheduleResponse with optional error and originalError.

Rate this page: