> 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/create-listener.md).

# create\_listener

Reference for the \`create\_listener\` MCP tool.

Preview, then create or invite a private-feed listener.

## Contract

| Property                     | Value                 |
| ---------------------------- | --------------------- |
| Required scopes              | `mcp:listeners:write` |
| Read-only                    | `false`               |
| Destructive                  | `false`               |
| 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": "create_listener",
    "arguments": {
      "attributes": {
        "podcast_id": 42,
        "email": "listener@example.com",
        "expires_at": "2027-01-31T23:59:59Z"
      },
      "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",
  "additionalProperties": false,
  "properties": {
    "attributes": {
      "type": "object",
      "required": [
        "podcast_id"
      ],
      "additionalProperties": false,
      "properties": {
        "podcast_id": {
          "type": "integer",
          "minimum": 1
        },
        "email": {
          "type": "string",
          "minLength": 1
        },
        "username": {
          "type": "string",
          "minLength": 1
        },
        "password": {
          "type": "string",
          "minLength": 1
        },
        "expires_at": {
          "anyOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "anyOf": [
        {
          "required": [
            "email"
          ]
        },
        {
          "required": [
            "username"
          ]
        }
      ]
    },
    "dry_run": {
      "type": "boolean"
    },
    "idempotency_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    },
    "confirm": {
      "type": "string",
      "minLength": 1
    }
  },
  "oneOf": [
    {
      "type": "object",
      "required": [
        "attributes",
        "dry_run"
      ],
      "additionalProperties": false,
      "properties": {
        "attributes": {
          "type": "object",
          "required": [
            "podcast_id"
          ],
          "additionalProperties": false,
          "properties": {
            "podcast_id": {
              "type": "integer",
              "minimum": 1
            },
            "email": {
              "type": "string",
              "minLength": 1
            },
            "username": {
              "type": "string",
              "minLength": 1
            },
            "password": {
              "type": "string",
              "minLength": 1
            },
            "expires_at": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "anyOf": [
            {
              "required": [
                "email"
              ]
            },
            {
              "required": [
                "username"
              ]
            }
          ]
        },
        "dry_run": {
          "const": true
        },
        "idempotency_key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        }
      }
    },
    {
      "type": "object",
      "required": [
        "attributes",
        "idempotency_key",
        "confirm"
      ],
      "additionalProperties": false,
      "properties": {
        "attributes": {
          "type": "object",
          "required": [
            "podcast_id"
          ],
          "additionalProperties": false,
          "properties": {
            "podcast_id": {
              "type": "integer",
              "minimum": 1
            },
            "email": {
              "type": "string",
              "minLength": 1
            },
            "username": {
              "type": "string",
              "minLength": 1
            },
            "password": {
              "type": "string",
              "minLength": 1
            },
            "expires_at": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "anyOf": [
            {
              "required": [
                "email"
              ]
            },
            {
              "required": [
                "username"
              ]
            }
          ]
        },
        "dry_run": {
          "const": false
        },
        "idempotency_key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "confirm": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  ]
}
```

### Input field descriptions

No additional field descriptions are defined.

### Key constraints

* `attributes` requires: `podcast_id`.
* `attributes.podcast_id` has minimum 1.
* `attributes.email` has minimum length 1.
* `attributes.username` has minimum length 1.
* `attributes.password` has minimum length 1.
* `attributes` requires: `email`.
* `attributes` requires: `username`.
* `idempotency_key` has minimum length 1 and maximum length 255.
* `confirm` has minimum length 1.
* `request` requires: `attributes`, `dry_run`.
* `request` requires: `attributes`, `idempotency_key`, `confirm`.

## 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",
        "podcast_id",
        "status",
        "created_at",
        "updated_at"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "integer"
        },
        "podcast_id": {
          "type": "integer"
        },
        "email": {
          "type": "string"
        },
        "username": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "active",
            "inactive",
            "resent"
          ]
        },
        "expires_at": {
          "type": "string",
          "format": "date-time"
        },
        "created_at": {
          "type": "string",
          "format": "date-time"
        },
        "updated_at": {
          "type": "string",
          "format": "date-time"
        }
      },
      "anyOf": [
        {
          "required": [
            "email"
          ]
        },
        {
          "required": [
            "username"
          ]
        }
      ]
    },
    {
      "type": "object",
      "required": [
        "dry_run",
        "action",
        "attributes",
        "request_digest",
        "confirm"
      ],
      "additionalProperties": false,
      "properties": {
        "dry_run": {
          "const": true
        },
        "action": {
          "const": "create_listener"
        },
        "attributes": {
          "type": "object",
          "required": [
            "podcast_id",
            "password_supplied"
          ],
          "additionalProperties": false,
          "properties": {
            "podcast_id": {
              "type": "integer",
              "minimum": 1
            },
            "email": {
              "type": "string",
              "minLength": 1
            },
            "username": {
              "type": "string",
              "minLength": 1
            },
            "expires_at": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time"
                },
                {
                  "type": "null"
                }
              ]
            },
            "password_supplied": {
              "type": "boolean"
            }
          }
        },
        "request_digest": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "confirm": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  ]
}
```

### Output field descriptions

No additional field descriptions are defined.

## 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

* [Add a private-feed listener](/documentation/start-here/ai-agents/manage-private-feed-access/add-a-private-feed-listener.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/create-listener.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.
