# Check a feed before saving it

`POST https://api-vod-express.syncwords.com/v1/source-feeds/check`

Check a feed before saving it

Reads a feed the way a feed project reads it, before there is a project: the same checks and the same answer as `GET /projects/{id}/source-feed`. `sourceType` says how to read it: `RssSource` takes each item’s `<enclosure>`, `MrssSource` (the default) its `<media:content>`. Saving a project with this feed as its `sourceMedia` refuses it when `state` is `no_usable_items`, `unreachable` or `not_a_feed`. A result is reused for up to a minute.

**Guide:** [Media RSS feeds](/vod-express/concepts/inputs#media-rss-feeds)

## Request body

Example:

```json
{
  "url": "https://feeds.example.com/videos.xml",
  "sourceType": "MrssSource"
}
```

Schema:

```json
{
  "type": "object",
  "required": [
    "url"
  ],
  "additionalProperties": false,
  "properties": {
    "url": {
      "type": "string",
      "description": "The feed: `https://`, at most 2048 characters, on a host that resolves to a public address."
    },
    "sourceType": {
      "enum": [
        "RssSource",
        "MrssSource"
      ],
      "default": "MrssSource",
      "description": "How the feed is read: as an RSS feed, the media in each item’s `<enclosure>` (`RssSource`), or as a Media RSS feed, each item’s `<media:content>` (`MrssSource`)."
    }
  }
}
```

## Responses

### 200

OK

Example:

```json
{
  "data": {
    "url": "https://feeds.example.com/videos.xml",
    "sourceType": "MrssSource",
    "checkedAt": "2026-10-06T19:10:32.000Z",
    "state": "no_usable_items",
    "problem": "None of the feed’s 25 items has a media file to download (the first: no <media:content>). Each item needs a <media:content url=\"…\"> linking the file itself, such as an .mp4.",
    "httpStatus": 200,
    "items": 25,
    "usableItems": 0,
    "skippedItems": [
      {
        "guid": "https://www.example.com/video/6406369231112",
        "title": "Fisherman rescued after calling for help",
        "link": "https://www.example.com/video/6406369231112",
        "reason": "no <media:content>"
      }
    ]
  }
}
```

Schema:

```json
{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "$ref": "#/components/schemas/SourceFeed"
    }
  }
}
```

### 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"
}
```

### 413

The body is over 2 MB: `payload_too_large`.

Example:

```json
{
  "message": [
    "The request body is too large."
  ],
  "code": "payload_too_large"
}
```

Schema:

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

### 415

The body is neither JSON nor YAML: `unsupported_media_type`.

Example:

```json
{
  "message": [
    "Send the body as JSON (Content-Type: application/json) or YAML (Content-Type: application/yaml)."
  ],
  "code": "unsupported_media_type"
}
```

Schema:

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

### 422

No `url`, or one a project could not read: not `https://`, with a user name or password, or on a host that does not resolve to a public address; a `sourceType` other than the two (`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

### SourceFeed

`#/components/schemas/SourceFeed`

```json
{
  "type": "object",
  "required": [
    "url",
    "sourceType",
    "checkedAt",
    "state",
    "problem",
    "httpStatus",
    "items",
    "usableItems",
    "skippedItems"
  ],
  "properties": {
    "url": {
      "type": "string"
    },
    "sourceType": {
      "enum": [
        "RssSource",
        "MrssSource"
      ],
      "description": "How the feed was read: each item’s `<enclosure>` (`RssSource`) or `<media:content>` (`MrssSource`)."
    },
    "checkedAt": {
      "type": "string",
      "format": "date-time"
    },
    "state": {
      "enum": [
        "ok",
        "partial",
        "empty",
        "no_usable_items",
        "unreachable",
        "not_a_feed",
        "unchecked"
      ],
      "description": "`ok`: every item links a media file the project downloads. `partial`: some do; `skippedItems` lists the others. `empty`: no items yet. `no_usable_items`: none does, so nothing is processed. `unreachable`: no `2xx` answer, after up to 5 redirects (never from HTTPS to HTTP). `not_a_feed`: the answer is not an RSS 2.0 document. `unchecked`: larger than 20 MB, which the check does not read."
    },
    "problem": {
      "type": [
        "string",
        "null"
      ],
      "description": "What is wrong, in a sentence; null for `ok` and `empty`."
    },
    "httpStatus": {
      "type": [
        "integer",
        "null"
      ],
      "description": "The feed’s HTTP status; null when it did not answer."
    },
    "items": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Null when the feed could not be read."
    },
    "usableItems": {
      "type": [
        "integer",
        "null"
      ]
    },
    "skippedItems": {
      "type": "array",
      "description": "The first 50 items the project skips, and why.",
      "items": {
        "type": "object",
        "required": [
          "guid",
          "title",
          "link",
          "reason"
        ],
        "properties": {
          "guid": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "link": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": "string"
          }
        }
      }
    }
  }
}
```

### 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"
        }
      }
    }
  }
}
```
