> For the complete documentation index, see [llms.txt](https://docs.podigee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.podigee.com/documentation/start-here/ai-agents/mcp-tools/submit-to-platform.md).

# submit\_to\_platform

Reference for the \`submit\_to\_platform\` MCP tool.

Preview, then submit a podcast to a directory Podigee can submit to on the user's behalf: spotify, deezer, apple\_podcasts, listen\_notes. Use this when get\_distribution\_status reports a platform as not\_submitted with manual\_submission\_required false. For platforms that own their listing account, call explain\_distribution\_handoff instead: those need a one-time setup the user performs themselves.

## Contract

| Property                     | Value                |
| ---------------------------- | -------------------- |
| Required scopes              | `mcp:podcasts:write` |
| Read-only                    | `false`              |
| Destructive                  | `true`               |
| Idempotent                   | `true`               |
| May interact outside Podigee | `true`               |

The MCP annotations describe client behavior. The server still applies authorization, validation, preview, confirmation, ownership, and account boundaries at execution time.

## Example request

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "submit_to_platform",
    "arguments": {
      "podcast_id": 42,
      "platform_key": "apple_podcasts",
      "dry_run": true
    }
  }
}
```

The example uses placeholder IDs. Replace them with IDs returned for the connected account.

## Input schema

The structural schema below omits prose `description` fields so each line remains readable. The complete public descriptions follow the schema.

```json
{
  "type": "object",
  "required": [
    "podcast_id",
    "platform_key"
  ],
  "additionalProperties": false,
  "properties": {
    "podcast_id": {
      "type": "integer"
    },
    "platform_key": {
      "type": "string",
      "enum": [
        "spotify",
        "deezer",
        "apple_podcasts",
        "listen_notes"
      ]
    },
    "dry_run": {
      "type": "boolean"
    },
    "idempotency_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    },
    "confirm": {
      "type": "string",
      "minLength": 1
    }
  }
}
```

### Input field descriptions

No additional field descriptions are defined.

### Key constraints

* `request` requires: `podcast_id`, `platform_key`.
* `platform_key` accepts: `spotify`, `deezer`, `apple_podcasts`, `listen_notes`.
* `idempotency_key` has minimum length 1 and maximum length 255.
* `confirm` has minimum length 1.

## Output schema

The `structuredContent` object in a successful tool result matches this schema.

The structural schema below omits prose `description` fields. The complete public descriptions follow the schema.

```json
{
  "type": "object",
  "oneOf": [
    {
      "type": "object",
      "required": [
        "id",
        "type",
        "status",
        "platform_key",
        "submitted_now"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "integer"
        },
        "type": {
          "type": "string"
        },
        "platform_key": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "not_submitted",
            "submitted",
            "in_review",
            "live",
            "rejected",
            "deactivated"
          ]
        },
        "state": {
          "type": "string"
        },
        "active": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "submitted": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ]
        },
        "submitted_on": {
          "type": "string",
          "format": "date-time"
        },
        "uid": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "external_url": {
          "type": "string"
        },
        "status_reason": {
          "type": "string"
        },
        "manual_submission_required": {
          "type": "boolean"
        },
        "submitted_now": {
          "type": "boolean"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "dry_run",
        "action",
        "podcast_id",
        "platform_key",
        "current_status",
        "request_digest",
        "confirm"
      ],
      "additionalProperties": false,
      "properties": {
        "dry_run": {
          "const": true
        },
        "action": {
          "const": "submit_to_platform"
        },
        "podcast_id": {
          "type": "integer"
        },
        "platform_key": {
          "type": "string"
        },
        "current_status": {
          "type": "string"
        },
        "feed_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "request_digest": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "confirm": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  ]
}
```

### Output field descriptions

### `(oneOf 1).platform_key`

Stable platform identifier. Pass this to explain\_distribution\_handoff when manual\_submission\_required is true.

### `(oneOf 1).status`

Normalized across platforms. Podigee creates a connection row for every platform when a podcast is created, so not\_submitted is the default and does not indicate a problem.

### `(oneOf 1).state`

The platform's own state name. Only some platforms track one.

### `(oneOf 1).active`

A webplayer and posting toggle, not a submission signal. It is false on every directory row Podigee creates and stays false on a show that is live. Read status instead.

### `(oneOf 1).external_url`

Public listing URL. Present only once the show is reachable there.

### `(oneOf 1).status_reason`

Why the platform is rejected or deactivated. Present only for those statuses. When Podigee receives no reason from the platform this says so, so treat it as the complete answer rather than looking further.

### `(oneOf 1).manual_submission_required`

True when the platform owns the account, so a human claims the show there once. This is one-time setup, not a standing limit on automation: once status is live, publishing through Podigee reaches this platform with no further manual step.

## Safety and retries

Use `dry_run: true` to inspect the normalized plan before any consequential change. When the preview requires confirmation, repeat the same request with the exact returned `confirm` value before it expires. Reuse one stable `idempotency_key` for retries of the same intended action. Use a new key for a different action.

Do not retry validation, authorization, plan, or ownership errors unchanged. Retry transient errors only when the response marks them as retryable. For durable work, use the returned operation ID instead of starting the same action again.

## Related guides

* [Submit a podcast to a supported platform](/documentation/start-here/ai-agents/distribute-a-podcast/submit-a-podcast-to-a-supported-platform.md)
* [Understand platform support and handoff types](/documentation/start-here/ai-agents/distribute-a-podcast/understand-platform-support-and-handoff-types.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.podigee.com/documentation/start-here/ai-agents/mcp-tools/submit-to-platform.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
