Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/xcoder-es/media-cleaner-pro/llms.txt

Use this file to discover all available pages before exploring further.

The /api/progress endpoint opens a persistent Server-Sent Events (SSE) connection and pushes a StateResponse snapshot to the client every 500 milliseconds. This is the recommended way to drive live progress indicators in a frontend UI without polling. The server also emits a keep-alive ping every second so that proxies and firewalls do not close the idle connection between updates.
GET /api/progress
The log_messages array is always empty in SSE payloads to keep event sizes small. Use GET /api/logs to retrieve the full log history, or GET /api/status for a one-shot snapshot that includes logs.

Response format

The endpoint responds with Content-Type: text/event-stream. Each push is a standard SSE message with the event name progress and a JSON-encoded StateResponse as the data payload.
event: progress
data: <StateResponse JSON>
The StateResponse payload contains the same fields as GET /api/statusstages, stats, is_running, and is_paused — with log_messages omitted (always an empty array).
The stream runs indefinitely until the client closes the connection. There is no terminal event. Close the EventSource (or the TCP connection for curl) when you no longer need updates.

Keep-alive

The server sends a keep-alive comment every 1 second to prevent proxies from timing out the connection:
: keep-alive
These lines are ignored by the SSE specification and do not trigger the message event handler.

Examples

Stream events from the terminal
curl -N http://127.0.0.1:8080/api/progress
Listen with the browser EventSource API
const source = new EventSource('http://127.0.0.1:8080/api/progress');

source.addEventListener('progress', (event) => {
  const state = JSON.parse(event.data);
  console.log(`Running: ${state.is_running}, Speed: ${state.stats.speed.toFixed(1)} files/sec`);
});

source.onerror = () => source.close();
Example SSE event
event: progress
data: {"stages":[{"name":"Exact Duplicate Removal","description":"Removes byte-for-byte identical files using SHA-256 hashing.","status":"completed","progress":100,"processed":3200,"total":3200,"started_at":"2024-06-01T10:23:45.000Z","completed_at":"2024-06-01T10:24:10.500Z","error":null},{"name":"Perceptual Duplicate Detection","description":"Detects visually similar images using dHash and Hamming distance.","status":"running","progress":62,"processed":1984,"total":3200,"started_at":"2024-06-01T10:24:10.501Z","completed_at":null,"error":null}],"stats":{"unique_count":1240,"duplicate_count":88,"error_count":0,"speed":142.3,"eta_seconds":45,"memory_mb":214,"cpu_percent":68.1,"current_file":"/home/user/photos/2024/IMG_5210.jpg","current_dhash":"A1B2C3D4E5F60718"},"is_running":true,"is_paused":false,"log_messages":[]}
In production frontends, debounce your render calls — at 500 ms intervals you will receive two events per second. For lower-frequency updates, apply a throttle on the consumer side rather than closing and reopening the stream.

Build docs developers (and LLMs) love