# On-Demand Algorithm Execution

Run additional algorithms on existing job transcripts without re-transcribing audio. Webhook delivery is optional via the `analytics_only` flag.

## Overview

The On-Demand Algorithm Execution API enables you to:

- **Analytics-only processing**: Run algorithms that store results but don't send webhooks
- **Backfill historical data**: Run new algorithms on existing transcripts
- **Re-analysis**: Re-run algorithms with updated configurations
- **Ad-hoc analysis**: Run one-off algorithms not configured during ingestion


## How It Works

When you call `POST /api/v1/jobs/{job_id}/run-algorithms`:

1. **Creates a child job** starting at `analyzing` state (skips transcription)
2. **Copies the transcript** from the original job
3. **Runs only specified algorithms** using `requested_algorithm_ids`
4. **Respects `analytics_only`** flag to skip webhook delivery
5. **Stores results** in `algorithm_runs` for the new job


The original job remains unchanged.

## Basic Usage

### Run Analytics-Only Algorithms

```bash
curl -X POST "https://analytics-api.gensail.com/api/v1/jobs/8835/run-algorithms" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "algorithm_ids": ["sentiment_v1", "competitor_mentions_v1"],
    "analytics_only": true
  }'
```

**Response (202 Accepted):**

```json
{
  "job_id": 9500,
  "parent_job_id": 8835,
  "algorithm_ids": ["sentiment_v1", "competitor_mentions_v1"],
  "status": "analyzing",
  "message": "On-demand analysis job created"
}
```

### Run with Webhook Delivery

Set `analytics_only: false` to send results via configured webhooks:

```bash
curl -X POST "https://analytics-api.gensail.com/api/v1/jobs/8835/run-algorithms" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "algorithm_ids": ["appointment_scheduling"],
    "analytics_only": false
  }'
```

**Note:** The child job uses its own webhook settings, NOT the parent's. Set `analytics_only: false` to enable webhooks even if the parent was analytics-only.

### Poll for Results

After creating the on-demand job, poll for status and results:

```bash
# Check job status
curl "https://analytics-api.gensail.com/api/v1/jobs/9500" \
  -H "Authorization: Bearer YOUR_TOKEN"

# Get algorithm run results
curl "https://analytics-api.gensail.com/api/v1/jobs/9500/runs" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Request Parameters

| Parameter | Type | Default | Description |
|  --- | --- | --- | --- |
| `algorithm_ids` | string[] | required | Algorithms to run (1-10, duplicates auto-deduped) |
| `analytics_only` | boolean | `true` | Skip webhook delivery |
| `force_rerun` | boolean | `false` | Run even if algorithms already ran |


## Idempotency

By default, if the requested algorithms already ran on the original job, the API returns the existing runs:

```json
{
  "message": "Algorithms already ran on this job",
  "existing_runs": [
    {"algorithm_run_id": 2001, "algorithm_id": "sentiment_v1", "status": "completed"}
  ],
  "hint": "Use force_rerun=true to run again"
}
```

Use `force_rerun: true` to bypass this check and create a new job:

```bash
curl -X POST "https://analytics-api.gensail.com/api/v1/jobs/8835/run-algorithms" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "algorithm_ids": ["appointment_scheduling"],
    "force_rerun": true
  }'
```

## Algorithm Availability

Requested algorithms must be available to the workspace. Available algorithms include:

1. **Global algorithms** (partner_id = NULL, organization_id = NULL)
2. **Partner-scoped algorithms** (linked via partner → organization)
3. **Workspace-assigned algorithms** (explicitly enabled for the workspace)


If an algorithm is not available, the API returns a 400 error:

```json
{
  "detail": "Algorithms not available: ['unknown_algo']"
}
```

## Validation Requirements

The original job must meet these requirements:

| Requirement | Error |
|  --- | --- |
| Job must exist | 404 Not Found |
| Auth must have access | 403 Forbidden |
| Job must be completed/partial/failed | 400 "Job is still {status}. Wait for completion." |
| Transcript must exist and be non-empty | 400 "Job has no usable transcript" |


## Use Cases

### Backfill Historical Data

Run a new algorithm on all completed jobs from the past month:

```python
import requests

# List completed jobs from the past month
jobs_response = requests.get(
    "https://analytics-api.gensail.com/api/v1/jobs",
    params={"status": "completed", "since": "30d"},
    headers={"Authorization": f"Bearer {TOKEN}"}
)

# Run the new algorithm on each job
for job in jobs_response.json()["jobs"]:
    requests.post(
        f"https://analytics-api.gensail.com/api/v1/jobs/{job['job_id']}/run-algorithms",
        json={"algorithm_ids": ["new_sentiment_v2"]},
        headers={"Authorization": f"Bearer {TOKEN}"}
    )
```

### Analytics-Only Data Lake

Store algorithm outputs without triggering partner webhooks:

```bash
curl -X POST "https://analytics-api.gensail.com/api/v1/jobs/8835/run-algorithms" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "algorithm_ids": ["internal_metrics_v1", "qa_scoring_v1"],
    "analytics_only": true
  }'
```

Results are stored in `algorithm_runs` and available via `GET /jobs/{id}/runs`.

### Compare Algorithm Versions

Re-run an algorithm with updated prompts/configuration:

```bash
# Run the updated algorithm version
curl -X POST "https://analytics-api.gensail.com/api/v1/jobs/8835/run-algorithms" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "algorithm_ids": ["rise_dds_v5"],
    "analytics_only": true
  }'
```

Compare results from the child job (v5) with the original job (v4).

## Rate Limiting

The endpoint uses scope-based rate limits matching other authenticated endpoints:

- **Workspace keys**: 50 requests/minute
- **Organization keys**: 120 requests/minute
- **Partner keys**: 500 requests/minute


For large backfills, implement client-side throttling:

- Batch requests appropriately for your key scope
- Use exponential backoff on 429 responses


## Related Documentation

- [Job Status API](/gensail-analytics/openapi/openapi) - Poll job status
- [Algorithm Runs API](/gensail-analytics/openapi/openapi) - Fetch algorithm results
- [Webhook Payloads](/gensail-analytics/guides/webhook-payloads) - Webhook payload format


## Support

For questions about on-demand algorithm execution, contact [support@gensail.com](mailto:support@gensail.com).