Skip to main content
Polling allows you to monitor session progress and retrieve results by periodically checking the session status. This is an alternative to webhooks that’s useful when you can’t receive incoming HTTP requests or prefer a pull-based approach.

When to use polling vs webhooks

Use CaseRecommended Approach
Server-side applications that can receive HTTP requestsWebhooks
Client-side applications (browser, mobile)Polling
Serverless functions with short timeoutsWebhooks
Local development without ngrokPolling
Real-time progress monitoringPolling
Fire-and-forget batch processingWebhooks

Basic usage

import { SimplexClient, SessionStatusResponse } from 'simplex-ts';

const client = new SimplexClient({
  apiKey: process.env.SIMPLEX_API_KEY!
});

// Start a workflow
const result = await client.workflows.run(workflowId, {
  variables: { url: 'https://example.com' }
});

const sessionId = result.session_id;

// Poll until complete
let status: SessionStatusResponse;
do {
  status = await client.getSessionStatus(sessionId);

  if (status.in_progress) {
    console.log('Session still running...');
    await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
  }
} while (status.in_progress);

// Session complete
if (status.success) {
  console.log('Session completed successfully!');
  console.log('Files downloaded:', status.file_metadata);
} else {
  console.log('Session failed');
}

Response structure

When polling session status, you’ll receive a response with the following fields:
{
  "in_progress": true,              // true while session is running
  "success": null,                  // null during session, true/false when complete
  "metadata": {},                   // custom metadata you provided when starting the session
  "workflow_metadata": {},          // metadata from the workflow definition
  "file_metadata": [                // files downloaded during the session
    {
      "filename": "report.pdf",
      "download_url": "https://...",
      "file_size": 102400,
      "download_timestamp": "2024-01-15T10:30:00Z",
      "session_id": "abc123"
    }
  ]
}

Field descriptions

FieldTypeDescription
in_progressbooleantrue if the session is still running, false when complete
successboolean | nullSession outcome: null while running, true if successful, false if failed
metadataobject | nullCustom metadata provided when starting the session
workflow_metadataobject | nullMetadata defined in the workflow configuration
file_metadataarray | nullList of files downloaded during the session

Polling with timeout

For production use, always implement a timeout to prevent infinite polling:
import { SimplexClient, SessionStatusResponse } from 'simplex-ts';

async function pollWithTimeout(
  client: SimplexClient,
  sessionId: string,
  timeoutMs: number = 300000,  // 5 minutes default
  intervalMs: number = 5000    // 5 seconds default
): Promise<SessionStatusResponse> {
  const startTime = Date.now();

  while (Date.now() - startTime < timeoutMs) {
    const status = await client.getSessionStatus(sessionId);

    if (!status.in_progress) {
      return status;
    }

    await new Promise(resolve => setTimeout(resolve, intervalMs));
  }

  throw new Error(`Polling timed out after ${timeoutMs}ms`);
}

// Usage
try {
  const status = await pollWithTimeout(client, sessionId, 600000); // 10 min timeout
  console.log('Session result:', status.success);
} catch (error) {
  console.error('Polling failed:', error);
}

Monitoring file downloads

The file_metadata field updates in real-time as files are downloaded during the session. You can use this to track download progress:
let lastFileCount = 0;

while (true) {
  const status = await client.getSessionStatus(sessionId);

  // Check for new files
  const currentFileCount = status.file_metadata?.length ?? 0;
  if (currentFileCount > lastFileCount) {
    const newFiles = status.file_metadata!.slice(lastFileCount);
    for (const file of newFiles) {
      console.log(`New file downloaded: ${file.filename} (${file.file_size} bytes)`);
    }
    lastFileCount = currentFileCount;
  }

  if (!status.in_progress) {
    break;
  }

  await new Promise(resolve => setTimeout(resolve, 5000));
}