# List input files

`GET https://api-vod-express.syncwords.com/v1/projects/{id}/files`

List input files

Every file in the project’s `input/` folder, subfolders included, in name order: its processing state and the outputs it produces. This is the call to poll: `meta` counts the files in each state, so the project is finished when `meta.pending` and `meta.processing` are both 0.

**Guide:** [Monitoring](/vod-express/guides/monitoring)

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The project id, a lowercase ULID. |
| `status` | query | string | no | Only the files in this state, or in any of several, comma-separated: `failed`, `pending,processing`. `meta` still counts every file. |

## Responses

### 200

OK

Example:

```json
{
  "data": [
    {
      "name": "episode 01.mp4",
      "size": 11825290,
      "uploadedAt": "2026-09-28T06:10:46.000Z",
      "status": "done",
      "hash": "a7381118",
      "outputs": [
        {
          "path": "episode 01.es.mp4",
          "available": true,
          "size": 12374212
        }
      ],
      "failureReason": null,
      "failureCode": null,
      "stale": false,
      "usage": [
        {
          "kind": "captioning",
          "language": "en",
          "durationMs": 1312480
        },
        {
          "kind": "translation",
          "language": "es",
          "durationMs": 1312480
        },
        {
          "kind": "dubbing",
          "language": "es",
          "durationMs": 1312480
        }
      ]
    },
    {
      "name": "season 2/episode 01.mp4",
      "size": 734003200,
      "uploadedAt": "2026-09-28T06:12:03.000Z",
      "status": "pending",
      "hash": null,
      "outputs": [
        {
          "path": "season 2/episode 01.es.mp4",
          "available": false,
          "size": null
        }
      ],
      "failureReason": null,
      "failureCode": null,
      "stale": false,
      "usage": null
    },
    {
      "name": "trailer.mp4",
      "size": 3174578,
      "uploadedAt": "2026-09-28T06:10:44.000Z",
      "status": "failed",
      "hash": null,
      "outputs": [
        {
          "path": "trailer.es.mp4",
          "available": false,
          "size": null
        }
      ],
      "failureReason": "Processing this file failed. Retry it, or contact support if it fails again.",
      "failureCode": "no_audio",
      "stale": false,
      "usage": null
    }
  ],
  "meta": {
    "total": 3,
    "pending": 1,
    "processing": 0,
    "done": 1,
    "failed": 1
  }
}
```

Schema:

```json
{
  "type": "object",
  "required": [
    "data",
    "meta"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/InputFile"
      }
    },
    "meta": {
      "$ref": "#/components/schemas/FileCounts"
    }
  }
}
```

### 401

No token, or an expired or unknown one: `unauthenticated`.

Example:

```json
{
  "message": "Unauthenticated.",
  "code": "unauthenticated"
}
```

Schema:

```json
{
  "$ref": "#/components/schemas/Error"
}
```

### 403

VOD Express is not available to the account: switched off for it (`vod_express_not_enabled`), or the account is restricted — its access revoked, its trial expired or used up (`account_restricted`, with the reason in `message`).

Example:

```json
{
  "message": [
    "VOD Express is not enabled for your account."
  ],
  "code": "vod_express_not_enabled"
}
```

Schema:

```json
{
  "$ref": "#/components/schemas/Error"
}
```

### 404

No such project in your account: `project_not_found`.

Example:

```json
{
  "message": "Project not found.",
  "code": "project_not_found"
}
```

Schema:

```json
{
  "$ref": "#/components/schemas/Error"
}
```

### 422

A `status` that is not a file state: `validation_failed`.

Example:

```json
{
  "message": "The selected status is invalid.",
  "errors": {
    "status": [
      "The selected status is invalid."
    ]
  },
  "code": "validation_failed"
}
```

Schema:

```json
{
  "$ref": "#/components/schemas/Error"
}
```

### 429

Rate limited: `too_many_requests`. Wait the seconds `Retry-After` says, then repeat the call.

Example:

```json
{
  "message": [
    "Too Many Attempts."
  ],
  "code": "too_many_requests"
}
```

Schema:

```json
{
  "$ref": "#/components/schemas/Error"
}
```

## Schemas

### InputFile

`#/components/schemas/InputFile`

```json
{
  "type": "object",
  "required": [
    "name",
    "size",
    "uploadedAt",
    "status",
    "hash",
    "outputs",
    "failureReason"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "The file’s path under `input/`: `season 2/episode 01.mp4` for a file in a subfolder."
    },
    "size": {
      "type": "integer",
      "description": "Bytes."
    },
    "uploadedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "status": {
      "enum": [
        "pending",
        "processing",
        "done",
        "failed"
      ],
      "description": "`pending`: waiting, or being transcribed, translated and dubbed (most of a file’s time); also a retried file until its new run gets that far, and a replaced one (`stale`). `processing`: the outputs are being written. `done`: every output is written. `failed`: see `failureCode`, and retry."
    },
    "hash": {
      "type": [
        "string",
        "null"
      ],
      "description": "The file’s processing key, the same for every run of this name in the project. Quote it to support."
    },
    "outputs": {
      "type": "array",
      "description": "Every output the config produces for this input.",
      "items": {
        "type": "object",
        "required": [
          "path",
          "available",
          "size"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Its path under `output/`."
          },
          "available": {
            "type": "boolean",
            "description": "Written yet."
          },
          "size": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      }
    },
    "failureReason": {
      "type": [
        "string",
        "null"
      ],
      "description": "Set on a `failed` file: that it failed and can be retried."
    },
    "failureCode": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "no_audio",
        "not_media",
        "voice_not_found",
        "interrupted",
        "internal",
        null
      ],
      "description": "Set on a `failed` file: why. `no_audio`: the file has no audio track, so there is nothing to dub. `not_media`: the file is not media, or is truncated; upload it again under a new name. `voice_not_found`: the config names a voice the engine does not have; correct it and retry. `interrupted`: processing was stopped before it finished (the worker was replaced, or the project stopped); retry the file. `internal`: a problem on our side; retry once, then contact support."
    },
    "stale": {
      "type": "boolean",
      "description": "The input was replaced (copied over with the AWS CLI) after it was processed: `status` is `pending`, and the outputs are still the old content’s. Retry the file to process the new content."
    },
    "usage": {
      "type": [
        "array",
        "null"
      ],
      "description": "What a `done` file was billed for: one entry for its captions in the source language, one translation per target language, and one dub per dubbed language, each by the input’s length. Retrying the same content bills nothing new, so a retried file keeps its first run’s entries; a replaced file is billed again. `null` for a file that is not `done`, and for up to a minute after it finishes, until it is recorded.",
      "items": {
        "type": "object",
        "required": [
          "kind",
          "language",
          "durationMs"
        ],
        "properties": {
          "kind": {
            "enum": [
              "captioning",
              "translation",
              "dubbing"
            ]
          },
          "language": {
            "type": "string",
            "description": "The source language for `captioning`, the target language otherwise."
          },
          "durationMs": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The input’s length in milliseconds, which the entry is billed by. `null` while processing has not reported a length; the entry is billed once it has."
          }
        }
      }
    }
  }
}
```

### FileCounts

`#/components/schemas/FileCounts`

```json
{
  "type": "object",
  "description": "How many of the project’s files are in each state.",
  "required": [
    "total",
    "pending",
    "processing",
    "done",
    "failed"
  ],
  "properties": {
    "total": {
      "type": "integer"
    },
    "pending": {
      "type": "integer"
    },
    "processing": {
      "type": "integer"
    },
    "done": {
      "type": "integer"
    },
    "failed": {
      "type": "integer"
    }
  }
}
```

### Error

`#/components/schemas/Error`

```json
{
  "type": "object",
  "required": [
    "message",
    "code"
  ],
  "properties": {
    "message": {
      "description": "For people. A string, or an array of one string on some statuses: read it as `Array.isArray(m) ? m[0] : m`.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "code": {
      "description": "For programs: stable, one per situation. See the Errors guide.",
      "enum": [
        "bad_request",
        "invalid_output_path",
        "invalid_idempotency_key",
        "unauthenticated",
        "invalid_credentials",
        "forbidden",
        "vod_express_not_enabled",
        "account_restricted",
        "not_found",
        "project_not_found",
        "file_not_found",
        "file_meta_not_found",
        "output_not_found",
        "feed_not_found",
        "upload_not_found",
        "webhook_not_found",
        "webhook_delivery_not_found",
        "aws_access_not_provisioned",
        "storage_connection_not_found",
        "method_not_allowed",
        "conflict",
        "file_exists",
        "project_reads_feed",
        "project_reads_folder",
        "file_processing",
        "project_config_locked",
        "idempotency_in_progress",
        "storage_connection_in_use",
        "payload_too_large",
        "unsupported_media_type",
        "validation_failed",
        "service_start_failed",
        "idempotency_key_reused",
        "webhook_limit_reached",
        "storage_failed",
        "storage_connection_check_failed",
        "storage_connection_folder_only",
        "storage_prefix_taken",
        "build_without_storage_connections",
        "build_has_no_schema",
        "too_many_requests",
        "internal_error",
        "bad_gateway",
        "service_stop_failed",
        "aws_access_failed",
        "platform_unavailable",
        "service_unavailable",
        "build_list_unavailable"
      ]
    },
    "errors": {
      "type": "object",
      "description": "On a 422: each field’s messages, keyed by field name, or by JSON pointer inside `config`.",
      "additionalProperties": {
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    }
  }
}
```
