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

# Stream Denoise Progress

> Subscribe to live progress events for a denoising job over Server-Sent Events (SSE). Emits processing updates and terminates with either a done event (carrying the final audio URL) or an error event. If the job is already complete the cached terminal event is replayed immediately.

Subscribes to live progress events for a denoising job over **Server-Sent Events (SSE)**. The connection emits a `processing` event as work advances and terminates with either a `done` event (carrying the final audio URL) or an `error` event.

## Authentication

Requires API key authentication via `x-api-key` header.

## Request

### Path Parameters

| Parameter   | Type          | Required | Description                                                            |
| ----------- | ------------- | -------- | ---------------------------------------------------------------------- |
| `denoiseId` | string (UUID) | Yes      | The `denoiseId` returned by [`POST /denoise`](/api-reference/denoise). |

### Headers

| Header   | Value               | Description                             |
| -------- | ------------------- | --------------------------------------- |
| `Accept` | `text/event-stream` | Required to negotiate the SSE response. |

## Response

**Status Code:** `200 OK`

**Headers:**

* `Content-Type: text/event-stream`
* `Cache-Control: no-cache`
* `Connection: keep-alive`

The body is an SSE stream. Each message is delivered as a `data:` line whose payload is a JSON object. The connection automatically closes after a terminal event (`done` or `error`), or after **15 minutes** of inactivity.

When you connect to an already-completed job, the server immediately emits the cached final event and closes — no need to poll separately.

### Event Schema

The `stage` field discriminates the event:

| Stage        | Fields                                              | Description                                         |
| ------------ | --------------------------------------------------- | --------------------------------------------------- |
| `processing` | `pct` (number, 0–100), `message` (string, optional) | Incremental progress update.                        |
| `done`       | `url` (string), `denoiseId` (string)                | Terminal success — `url` is the denoised audio URL. |
| `error`      | `message` (string)                                  | Terminal failure — human-readable error message.    |

### Example Stream

```text theme={null}
data: {"stage":"processing","pct":15,"message":"Extracting audio"}

data: {"stage":"processing","pct":62,"message":"Running noise reduction"}

data: {"stage":"done","url":"https://cdn.munsit.com/denoising/user_123/5b1d2f7e_denoised.wav","denoiseId":"5b1d2f7e-3f81-4c2a-9c5d-7a2e91b4c7a1"}
```

### Error Responses

**404 Not Found** — emitted as a JSON body, not as SSE:

```json theme={null}
{
  "message": "Denoising job not found"
}
```

**401 Unauthorized**

```json theme={null}
{
  "errorCode": "40101",
  "errorMessage": "Invalid or missing API key"
}
```

## Example Usage

### JavaScript (fetch + ReadableStream)

```javascript theme={null}
const denoiseId = "5b1d2f7e-3f81-4c2a-9c5d-7a2e91b4c7a1";

const res = await fetch(`https://api.munsit.com/api/v1/denoise/${denoiseId}/progress`, {
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Accept': 'text/event-stream',
  },
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop() ?? "";

  for (const line of lines) {
    if (!line.startsWith("data: ")) continue;
    const event = JSON.parse(line.slice(6));
    if (event.stage === "processing") {
      console.log(`Progress: ${event.pct}%`, event.message);
    } else if (event.stage === "done") {
      console.log("Denoised audio ready:", event.url);
      return;
    } else if (event.stage === "error") {
      console.error("Denoising failed:", event.message);
      return;
    }
  }
}
```

### Python (httpx)

```python theme={null}
import httpx, json

denoise_id = "5b1d2f7e-3f81-4c2a-9c5d-7a2e91b4c7a1"
url = f"https://api.munsit.com/api/v1/denoise/{denoise_id}/progress"
headers = {
    "x-api-key": "YOUR_API_KEY",
    "Accept": "text/event-stream",
}

with httpx.stream("GET", url, headers=headers, timeout=None) as r:
    for line in r.iter_lines():
        if not line or not line.startswith("data: "):
            continue
        event = json.loads(line[6:])
        if event["stage"] == "processing":
            print(f"Progress: {event['pct']}% — {event.get('message','')}")
        elif event["stage"] == "done":
            print("Denoised audio URL:", event["url"])
            break
        elif event["stage"] == "error":
            print("Failed:", event["message"])
            break
```

### cURL

```bash theme={null}
curl -N "https://api.munsit.com/api/v1/denoise/5b1d2f7e-3f81-4c2a-9c5d-7a2e91b4c7a1/progress" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: text/event-stream"
```

<Note>
  **Reconnecting**: If you reconnect after a job has already finished, the server replays the cached terminal event immediately so clients never miss completion.
</Note>


## OpenAPI

````yaml GET /denoise/{denoiseId}/progress
openapi: 3.1.0
info:
  title: Munsit API
  description: >-
    Munsit - First True Arabic Voice AI that speaks Dialects From Abu Dhabi to
    Rabat with Voice Cloning & On-prem support
  version: 1.0.0
servers:
  - url: https://api.munsit.com/api/v1
    description: Global production server
  - url: https://ae.api.faseeh.ai/api/v1
    description: UAE regional server
security:
  - apiKeyAuth: []
paths:
  /denoise/{denoiseId}/progress:
    get:
      tags:
        - Voice Isolation
      summary: Stream Denoise Progress
      description: >-
        Subscribe to live progress events for a denoising job over Server-Sent
        Events (SSE). Emits processing updates and terminates with either a done
        event (carrying the final audio URL) or an error event. If the job is
        already complete the cached terminal event is replayed immediately.
      operationId: denoiseProgress
      parameters:
        - in: path
          name: denoiseId
          required: true
          schema:
            type: string
            format: uuid
          description: The denoiseId returned by POST /denoise.
      responses:
        '200':
          description: >-
            SSE stream of denoising events. Each message is a `data: <json>`
            line where the JSON conforms to DenoiseProgressEvent.
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/DenoiseProgressEvent'
        '401':
          description: Unauthorized - Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Denoising job not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Denoising job not found
components:
  schemas:
    DenoiseProgressEvent:
      description: >-
        An SSE event payload for a denoising job. The stage field discriminates
        between processing, done, and error.
      oneOf:
        - type: object
          required:
            - stage
            - pct
          properties:
            stage:
              type: string
              enum:
                - processing
            pct:
              type: number
              minimum: 0
              maximum: 100
              description: Completion percentage.
            message:
              type: string
              description: Optional human-readable progress message.
        - type: object
          required:
            - stage
            - url
            - denoiseId
          properties:
            stage:
              type: string
              enum:
                - done
            url:
              type: string
              description: URL of the denoised audio file.
            denoiseId:
              type: string
              format: uuid
        - type: object
          required:
            - stage
            - message
          properties:
            stage:
              type: string
              enum:
                - error
            message:
              type: string
              description: Human-readable error message.
    Error:
      type: object
      required:
        - errorCode
        - errorMessage
      properties:
        errorCode:
          type: string
          description: Error code identifier
        errorMessage:
          type: string
          description: Human-readable error message
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for authentication

````