> ## Documentation Index
> Fetch the complete documentation index at: https://simplex.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Polling Session Status

> Using polling to monitor session progress

Polling allows you to monitor session progress and retrieve results by periodically checking the session status. This is an alternative to [webhooks](/docs/integrating-simplex/webhooks) that's useful when you can't receive incoming HTTP requests or prefer a pull-based approach.

## Usage

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    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: { patient_id: 'P-12345', insurance_provider: 'Blue Cross' }
    });

    const sessionId = result.session_id;

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

      if (status.paused) {
        console.log('Session paused, waiting for resume...');
      } else if (status.in_progress) {
        console.log('Session still running...');
      }

      if (status.in_progress) {
        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);
      console.log('Agent summary:', status.final_message);
    } else {
      console.log('Session failed');
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    import time
    from simplex import SimplexClient

    client = SimplexClient(api_key=os.environ["SIMPLEX_API_KEY"])

    workflow_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

    # Start a workflow
    result = client.run_workflow(
        workflow_id,
        variables={"patient_id": "P-12345", "insurance_provider": "Blue Cross"}
    )

    session_id = result["session_id"]

    # Poll until complete
    while True:
        status = client.get_session_status(session_id)

        if status.get("paused"):
            print("Session paused, waiting for resume...")
        elif status["in_progress"]:
            print("Session still running...")

        if status["in_progress"]:
            time.sleep(5)  # Wait 5 seconds
        else:
            break

    # Session complete
    if status["success"]:
        print("Session completed successfully!")
        print("Files downloaded:", status["file_metadata"])
        print("Agent summary:", status["final_message"])
    else:
        print("Session failed")
    ```
  </Tab>
</Tabs>

## Response structure

When polling session status, you'll receive a response with the following fields:

<ResponseField name="in_progress" type="boolean" required>
  `true` while the session is running, `false` when complete
</ResponseField>

<ResponseField name="success" type="boolean | null" required>
  Session outcome: `null` while running, `true` if successful, `false` if failed
</ResponseField>

<ResponseField name="workflow_metadata" type="object">
  Metadata set in the workflow definition
</ResponseField>

<ResponseField name="session_metadata" type="object">
  Custom metadata you provided when starting the session
</ResponseField>

<ResponseField name="file_metadata" type="array">
  Metadata for files downloaded during the session

  <Expandable title="properties">
    <ResponseField name="filename" type="string">
      Name of the downloaded file
    </ResponseField>

    <ResponseField name="download_url" type="string">
      Presigned URL to download the file
    </ResponseField>

    <ResponseField name="file_size" type="number">
      Size of the file in bytes
    </ResponseField>

    <ResponseField name="download_timestamp" type="string">
      ISO 8601 timestamp when the file was downloaded
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="scraper_outputs" type="array">
  Data collected by scraper actions during the session
</ResponseField>

<ResponseField name="structured_output" type="object | null">
  Structured output fields from workflow execution. `null` while the session is in progress, populated at session close.
</ResponseField>

<ResponseField name="final_message" type="string | null">
  A summary of what the agent accomplished. `null` while the session is in progress, populated at session close.
</ResponseField>

<ResponseField name="paused" type="boolean">
  `true` if the session is currently paused (waiting to be resumed), `false` otherwise
</ResponseField>

<ResponseField name="paused_key" type="string">
  The pause key identifier if the session is paused, empty string otherwise
</ResponseField>

## Polling with timeout

For production use, always implement a timeout to prevent infinite polling:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    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);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import time
    from simplex import SimplexClient, SessionStatusResponse

    def poll_with_timeout(
        client: SimplexClient,
        session_id: str,
        timeout_seconds: float = 300,  # 5 minutes default
        interval_seconds: float = 5    # 5 seconds default
    ) -> SessionStatusResponse:
        start_time = time.time()

        while time.time() - start_time < timeout_seconds:
            status = client.get_session_status(session_id)

            if not status["in_progress"]:
                return status

            time.sleep(interval_seconds)

        raise TimeoutError(f"Polling timed out after {timeout_seconds} seconds")

    # Usage
    try:
        status = poll_with_timeout(client, session_id, timeout_seconds=600)  # 10 min timeout
        print("Session result:", status["success"])
    except TimeoutError as e:
        print("Polling failed:", e)
    ```
  </Tab>
</Tabs>

## Monitoring file downloads

The `file_metadata` field updates in real-time as file\_metadata are downloaded during the session. You can use this to track download progress:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let lastFileCount = 0;

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

      // Check for new file_metadata
      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));
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import time

    last_file_count = 0

    while True:
        status = client.get_session_status(session_id)

        # Check for new file_metadata
        current_file_count = len(status["file_metadata"])
        if current_file_count > last_file_count:
            new_files = status["file_metadata"][last_file_count:]
            for file in new_files:
                print(f"New file downloaded: {file['filename']} ({file['file_size']} bytes)")
            last_file_count = current_file_count

        if not status["in_progress"]:
            break

        time.sleep(5)
    ```
  </Tab>
</Tabs>
