# How to Check the Status of a ReClip Download Job: Complete API Guide

> Easily check ReClip download job status using the API. Learn how to query downloading, done, or error states with the /api/status/<job_id> endpoint.

- Repository: [Avery Gan/reclip](https://github.com/averygan/reclip)
- Tags: api-reference
- Published: 2026-09-03

---

**Use the `/api/status/<job_id>` REST endpoint to query the current state of any ReClip download, which returns `"downloading"`, `"done"`, or `"error"` along with optional filename or error details.**

ReClip tracks every download through an in-memory job registry on its Flask backend. This guide shows you how to check the status of a ReClip download job using the REST API, with examples in `curl` and JavaScript that mirror the implementation in the `averygan/reclip` repository.

## How ReClip Tracks Download Jobs

When you start a download via `POST /api/download`, ReClip generates a UUID and registers the job in a global `jobs` dictionary.

In [`app.py`](https://github.com/averygan/reclip/blob/main/app.py), the download endpoint initializes each job with a **"downloading"** status:

```python

# app.py – line 78

jobs[job_id] = {"status": "downloading", "url": url, "title": title}

```

The job persists in memory until completion or failure, making the `job_id` your key to monitoring progress.

## The Status Endpoint: `/api/status/<job_id>`

The Flask backend exposes a simple GET endpoint to retrieve job state. In [`app.py`](https://github.com/averygan/reclip/blob/main/app.py) (lines 188–193), the `check_status()` function performs a dictionary lookup and returns the current status:

```python

# app.py – status endpoint

@app.route("/api/status/<job_id>")
def check_status(job_id):
    job = jobs.get(job_id)                                            # line 188

    if not job:
        return jsonify({"error": "Job not found"}), 404
    return jsonify({
        "status": job["status"],                                      # line 193

        "error": job.get("error"),
        "filename": job.get("filename"),
    })

```

### Response Format

| Field | Type | Description |
|-------|------|-------------|
| `status` | string | `"downloading"`, `"done"`, or `"error"` |
| `error` | string \| null | Error message if status is `"error"` |
| `filename` | string \| null | Generated filename if status is `"done"` |

## How the Frontend Polls for Status Updates

The ReClip UI implements real-time status checks using JavaScript polling. In [`templates/index.html`](https://github.com/averygan/reclip/blob/main/templates/index.html) (lines 558–573), each download card starts a `setInterval` loop that hits the status endpoint every second:

```javascript
// templates/index.html – polling loop
const iv = setInterval(async () => {
    const res = await fetch(`/api/status/${c.jobId}`);
    const data = await res.json();
    if (data.status === 'done') {
        clearInterval(iv);
        c.status = 'done';
        c.filename = data.filename;
        renderCard(idx);
        saveCard(idx);
    } else if (data.status === 'error') {
        clearInterval(iv);
        c.status = 'error';
        c.error = data.error;
        renderCard(idx);
    }
}, 1000);

```

The UI transitions automatically: **"downloading"** shows a spinner, **"done"** reveals a save button with the filename, and **"error"** displays the failure reason.

## Checking Status via Command Line with curl

For automation or scripting, poll the ReClip download job status using `curl` and `jq`:

```bash

# 1️⃣ Start a download and capture the job_id

job_id=$(curl -s -X POST -H "Content-Type: application/json" \
    -d '{"url":"https://www.youtube.com/watch?v=xyz","format":"video"}' \
    http://localhost:8899/api/download | jq -r .job_id)

# 2️⃣ Poll until completion or error

while true; do
    status=$(curl -s http://localhost:8899/api/status/$job_id | jq -r .status)
    echo "Current status: $status"
    [[ $status == "done" || $status == "error" ]] && break
    sleep 1
done

```

This pattern matches the frontend's polling strategy, adapted for shell scripts.

## Checking Status via JavaScript fetch API

To integrate ReClip status checks into your own application, use this async function:

```javascript
async function getJobStatus(jobId) {
    const resp = await fetch(`/api/status/${jobId}`);
    if (!resp.ok) throw new Error('Job not found');
    const {status, error, filename} = await resp.json();
    return {status, error, filename};
}

// Usage with polling
async function pollUntilComplete(jobId, onComplete, onError) {
    const interval = setInterval(async () => {
        const {status, error, filename} = await getJobStatus(jobId);
        if (status === 'done') {
            clearInterval(interval);
            onComplete(filename);
        } else if (status === 'error') {
            clearInterval(interval);
            onError(error);
        }
    }, 1000);
}

```

## Handling Edge Cases

**Job not found**: Returns HTTP 404 with `{"error": "Job not found"}`. This occurs if the server restarted (jobs are in-memory only) or if the `job_id` is invalid.

**Server restart**: Since `jobs` is a Python dictionary in [`app.py`](https://github.com/averygan/reclip/blob/main/app.py) with no persistence, all job status is lost if the Flask process restarts.

**Stale polling**: Always implement `clearInterval` or equivalent cleanup when status reaches a terminal state (`"done"` or `"error"`) to prevent unnecessary requests.

## Key Files in the ReClip Repository

| File | Purpose |
|------|---------|
| [`app.py`](https://github.com/averygan/reclip/blob/main/app.py) | Flask backend with `/api/status/<job_id>` endpoint and job registry |
| [`templates/index.html`](https://github.com/averygan/reclip/blob/main/templates/index.html) | Frontend UI with JavaScript polling implementation |
| [`reclip.sh`](https://github.com/averygan/reclip/blob/main/reclip.sh) | Convenience launcher for the Flask server |

## Summary

- **Obtain `job_id`** from the `POST /api/download` response
- **Query `GET /api/status/<job_id>`** to retrieve current state
- **Interpret three statuses**: `"downloading"` (in progress), `"done"` (complete with filename), `"error"` (failed with message)
- **Poll at 1-second intervals** as implemented in [`templates/index.html`](https://github.com/averygan/reclip/blob/main/templates/index.html) for real-time updates
- **Handle 404 errors** for missing or expired jobs

## Frequently Asked Questions

### What happens to job status if the ReClip server restarts?

All job status information is lost. ReClip stores jobs in a Python dictionary in memory (`jobs` in [`app.py`](https://github.com/averygan/reclip/blob/main/app.py)) with no disk persistence. After a restart, any `job_id` will return 404.

### How long does a job remain queryable?

Indefinitely, until server restart. The `jobs` dictionary accumulates entries without automatic cleanup for completed or errored jobs in the current implementation.

### Can I check status from a different machine or process?

Yes, as long as you have network access to the ReClip server and the correct `job_id`. The REST endpoint has no session or origin restrictions—any client can query any valid job ID.

### Why does my status request return 404 for a job I just started?

Either the server restarted between your download request and status check, or the `job_id` was not captured correctly from the `POST /api/download` response. Verify the exact UUID string including dashes.