# Polls

The Polls feature provides a comprehensive API that enables seamless integration of polling capabilities within your application, enhancing engagement and interaction among users. Through this API, developers can effortlessly create, manage, and utilize polls as part of messages, gather user opinions, and make informed decisions based on real-time feedback.

## Key Features Include

- **Easy Poll Creation and Configuration**: Developers can create polls with customizable options, descriptions, and configurations, including setting voting visibility (public or anonymous), enforcing unique votes, and specifying the maximum votes a user can cast. Polls can also be designed to allow user-suggested options or open-ended answers, providing flexibility in how you engage with your audience.
- **Seamless Integration with Activities**: Once created, polls can be sent as part of activities, allowing for a seamless user experience. Users can view poll details and participate directly within the context of a conversation.
- **Dynamic Poll Management**: Polls are not static. You can update poll details, add or modify options, and even close polls to further responses. These actions can be performed through full or partial updates, giving you control over the poll's lifecycle.
- **Robust Voting System**: Users can cast votes on options or provide answers to open-ended questions, with the API supporting both single and multiple choice responses. Votes can be changed or removed, ensuring users' opinions are accurately captured.
- **Comprehensive Query Capabilities**: Retrieve detailed information about polls and votes based on various criteria, including poll status, creation time, and user responses. This enables developers to implement rich, data-driven features in their applications.
- **Customizability and Extensibility**: In addition to predefined poll properties, the API supports custom properties, allowing developers to tailor polls and options to their specific needs while maintaining performance and scalability.

## Creating a Poll and Sending it as Part of an Activity

Creating a poll is easy. You simply create a poll with your desired configuration, and once created, you post an activity with the poll id.

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Create a poll
let poll = try await feed.createPoll(
    request: CreatePollRequest(
        name: "Where should we host our next company event?",
        options: [
            PollOptionInput(text: "Amsterdam, The Netherlands"),
            PollOptionInput(text: "Boulder, CO")
        ]
    ),
    activityType: "poll"
)

// The poll is automatically added as an activity to the feed
print("Poll created with ID: \(poll.id)")
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
// Create a poll
val poll: Result<ActivityData> = feed.createPoll(
    request = CreatePollRequest(
        name = "Where should we host our next company event?",
        options = listOf(
            PollOptionInput(text = "Amsterdam, The Netherlands"),
            PollOptionInput(text = "Boulder, CO")
        )
    ),
    activityType = "poll"
)

// The poll is automatically added as an activity to the feed
println("Poll created with ID: ${poll.getOrNull()?.id}")
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const response = await client.createPoll({
  name: "Where should we host our next company event?",
  options: [{ text: "Amsterdam, The Netherlands" }, { text: "Boulder, CO" }],
});

// Attach poll to an activity
await feed.addActivity({
  type: "post",
  poll_id: response.poll.id,
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
const response = await client.createPoll({
  name: "Where should we host our next company event?",
  options: [{ text: "Amsterdam, The Netherlands" }, { text: "Boulder, CO" }],
});

// Attach poll to an activity
await feed.addActivity({
  type: "post",
  poll_id: response.poll.id,
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
const response = await client.createPoll({
  name: "Where should we host our next company event?",
  options: [{ text: "Amsterdam, The Netherlands" }, { text: "Boulder, CO" }],
});

// Attach poll to an activity
await feed.addActivity({
  type: "post",
  poll_id: response.poll.id,
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
// Create a poll
final poll = await feed.createPoll(
  request: const CreatePollRequest(
    name: 'Where should we host our next company event?',
    options: [
      PollOptionInput(text: 'Amsterdam, The Netherlands'),
      PollOptionInput(text: 'Boulder, CO'),
    ],
  ),
  activityType: 'poll',
);

// The poll is automatically added as an activity to the feed
print('Poll created with ID: ${poll.getOrThrow().id}');
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const response = await client.createPoll({
  name: "Where should we host our next company event?",
  options: [{ text: "Amsterdam, The Netherlands" }, { text: "Boulder, CO" }],
  user_id: "<user id>",
});

// Attach poll to an activity
await client.feeds.addActivity({
  fids: [feed.fid],
  type: "post",
  poll_id: response.poll.id,
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

// Create a poll
pollResponse, err := client.CreatePoll(ctx, &getstream.CreatePollRequest{
  Name:   "Where should we host our next company event?",
  UserID: getstream.PtrTo("john"),
  Options: []getstream.PollOptionInput{
    {Text: getstream.PtrTo("Amsterdam, The Netherlands")},
    {Text: getstream.PtrTo("Boulder, CO")},
  },
})
if err != nil {
  log.Fatal("Error creating poll:", err)
}

// Attach poll to an activity
activityResponse, err := client.Feeds().AddActivity(ctx, &getstream.AddActivityRequest{
  Type:   "post",
  PollID: getstream.PtrTo(pollResponse.Data.Poll.ID),
  UserID: getstream.PtrTo("john"),
  Feeds:  []string{"user:john"},
})
if err != nil {
  log.Fatal("Error adding activity:", err)
}
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# Create a poll
poll_request = GetStream::Generated::Models::CreatePollRequest.new(
  name: 'Where should we host our next company event?',
  user_id: 'user123',
  options: [
    GetStream::Generated::Models::PollOptionInput.new(
      text: 'Amsterdam, The Netherlands'
    ),
    GetStream::Generated::Models::PollOptionInput.new(
      text: 'Boulder, CO'
    )
  ]
)

poll_response = client.common.create_poll(poll_request)

# Attach poll to an activity
activity_request = GetStream::Generated::Models::AddActivityRequest.new(
  type: 'post',
  poll_id: poll_response.poll.id,
  user_id: 'user123',
  feeds: ['user:user123']
)

activity_response = client.feeds.add_activity(activity_request)
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
import io.getstream.services.CommonImpl;
import io.getstream.models.*;

CommonImpl common = new CommonImpl(new StreamHTTPClient("<API key>", "<API secret>"));

// Create a poll
CreatePollRequest pollRequest = CreatePollRequest.builder()
    .name("Where should we host our next company event?")
    .userID("user123")
    .options(List.of(
        PollOptionInput.builder().text("Amsterdam, The Netherlands").build(),
        PollOptionInput.builder().text("Boulder, CO").build()
    ))
    .build();

PollResponse pollResponse = common.createPoll(pollRequest).execute().getData();
String pollId = pollResponse.getPoll().getId();

// Attach poll to an activity
AddActivityRequest activityRequest = AddActivityRequest.builder()
    .type("post")
    .pollID(pollId)
    .userID("user123")
    .feeds(List.of("user:user123"))
    .build();

AddActivityResponse activityResponse = feedsClient.addActivity(activityRequest).execute().getData();
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
// Create a poll
var pollRequest = new CreatePollRequest
{
    Name = "Where should we host our next company event?",
    UserID = "user123",
    Options = new List<PollOptionInput>
    {
        new() { Text = "Amsterdam, The Netherlands" },
        new() { Text = "Boulder, CO" }
    }
};

var pollResponse = await _client.CreatePollAsync(pollRequest);
var pollId = pollResponse.Data.Poll.ID;

// Attach poll to an activity
var activityRequest = new AddActivityRequest
{
    Type = "post",
    PollID = pollId,
    UserID = "user123",
    Feeds = new List<string> { "user:user123" }
};

var activityResponse = await _feedsV3Client.AddActivityAsync(activityRequest);
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
# Create a poll
poll = {
    "name": "Where should we host our next company event?",
    "user_id": "user123",
    "options": [
        {"text": "Amsterdam, The Netherlands"},
        {"text": "Boulder, CO"}
    ]
}
poll_response = client.create_poll(**poll)
poll_id = poll_response.data.get("id")

# Attach poll to an activity
activity_response = client.feeds.add_activity(
    type="post",
    poll_id=poll_id,
    user_id="user123",
    feeds=["user:user123"]
)
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
// Create a poll
$pollRequest = new GeneratedModels\CreatePollRequest(
    name: 'Where should we host our next company event?',
    userID: 'user123',
    options: [
        new GeneratedModels\PollOptionInput(text: 'Amsterdam, The Netherlands'),
        new GeneratedModels\PollOptionInput(text: 'Boulder, CO')
    ]
);

$pollResponse = $client->createPoll($pollRequest);
$pollData = $pollResponse->getData();
$pollId = $pollData->poll->id;

// Attach poll to an activity
$activityRequest = new GeneratedModels\AddActivityRequest(
    type: 'post',
    pollID: $pollId,
    userID: 'user123',
    feeds: ['user:user123']
);

$activityResponse = $feedsClient->addActivity($activityRequest);
```

</codetabs-item>

</codetabs>

Please take into account that the poll can be sent only by the user who created it in the first place.

### Overview of the poll and vote models

<open-api-models modelname="PollResponseData" recursive="false" headerlevel="4">
</open-api-models>

<open-api-models modelname="PollOptionResponseData" recursive="false" headerlevel="4">
</open-api-models>

It is also possible to supply your own custom properties for both polls and options:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let poll = try await feed.createPoll(
    request: CreatePollRequest(
        custom: ["category": "event_planning", "priority": "high"],
        name: "Where should we host our next company event?",
        options: [
            PollOptionInput(
                custom: ["country": "Netherlands", "timezone": "CET"],
                text: "Amsterdam, The Netherlands"
            ),
            PollOptionInput(
                custom: ["country": "USA", "timezone": "MST"],
                text: "Boulder, CO"
            )
        ]
    ),
    activityType: "poll"
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val request = CreatePollRequest(
    custom = mapOf("category" to "event_planning", "priority" to "high"),
    name = "Where should we host our next company event?",
    options = listOf(
        PollOptionInput(
            custom = mapOf("country" to "Netherlands", "timezone" to "CET"),
            text = "Amsterdam, The Netherlands"
        ),
        PollOptionInput(
            custom = mapOf("country" to "USA", "timezone" to "MST"),
            text = "Boulder, CO"
        )
    )
)
val poll: Result<ActivityData> = feed.createPoll(
    request = request,
    activityType = "poll"
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.createPoll({
  name: "Where should we host our next company event?",
  options: [
    {
      text: "Amsterdam, The Netherlands",
      custom: {
        country: "Netherlands",
        timezone: "CET",
      },
    },
    {
      text: "Boulder, CO",
      custom: {
        country: "United States",
        timezone: "MST",
      },
    },
  ],
  custom: {
    category: "event_planning",
    priority: "high",
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.createPoll({
  name: "Where should we host our next company event?",
  options: [
    {
      text: "Amsterdam, The Netherlands",
      custom: {
        country: "Netherlands",
        timezone: "CET",
      },
    },
    {
      text: "Boulder, CO",
      custom: {
        country: "United States",
        timezone: "MST",
      },
    },
  ],
  custom: {
    category: "event_planning",
    priority: "high",
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.createPoll({
  name: "Where should we host our next company event?",
  options: [
    {
      text: "Amsterdam, The Netherlands",
      custom: {
        country: "Netherlands",
        timezone: "CET",
      },
    },
    {
      text: "Boulder, CO",
      custom: {
        country: "United States",
        timezone: "MST",
      },
    },
  ],
  custom: {
    category: "event_planning",
    priority: "high",
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final poll = await feed.createPoll(
  request: const CreatePollRequest(
    custom: {'category': 'event_planning', 'priority': 'high'},
    name: 'Where should we host our next company event?',
    options: [
      PollOptionInput(
        custom: {'country': 'Netherlands', 'timezone': 'CET'},
        text: 'Amsterdam, The Netherlands',
      ),
      PollOptionInput(
        custom: {'country': 'USA', 'timezone': 'MST'},
        text: 'Boulder, CO',
      ),
    ],
  ),
  activityType: 'poll',
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.createPoll({
  name: "Where should we host our next company event?",
  options: [
    {
      text: "Amsterdam, The Netherlands",
      custom: {
        country: "Netherlands",
        timezone: "CET",
      },
    },
    {
      text: "Boulder, CO",
      custom: {
        country: "United States",
        timezone: "MST",
      },
    },
  ],
  custom: {
    category: "event_planning",
    priority: "high",
  },
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.CreatePoll(ctx, &getstream.CreatePollRequest{
  Name: "Where should we host our next company event?",
  Options: []getstream.PollOptionInput{
    {
      Text: getstream.PtrTo("Amsterdam, The Netherlands"),
      Custom: map[string]any{
        "country":  "Netherlands",
        "timezone": "CET",
      },
    },
    {
      Text: getstream.PtrTo("Boulder, CO"),
      Custom: map[string]any{
        "country":  "United States",
        "timezone": "MST",
      },
    },
  },
  Custom: map[string]any{
    "category": "event_planning",
    "priority": "high",
  },
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal(err)
}
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
poll_request = GetStream::Generated::Models::CreatePollRequest.new(
  name: 'Where should we host our next company event?',
  user_id: 'user123',
  custom: {
    category: 'event_planning',
    priority: 'high'
  },
  options: [
    GetStream::Generated::Models::PollOptionInput.new(
      text: 'Amsterdam, The Netherlands',
      custom: {
        country: 'Netherlands',
        timezone: 'CET'
      }
    ),
    GetStream::Generated::Models::PollOptionInput.new(
      text: 'Boulder, CO',
      custom: {
        country: 'United States',
        timezone: 'MST'
      }
    )
  ]
)

poll_response = client.common.create_poll(poll_request)
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$pollRequest = new GeneratedModels\CreatePollRequest(
    name: 'Where should we host our next company event?',
    userID: 'user123',
    custom: (object)[
        'category' => 'event_planning',
        'priority' => 'high'
    ],
    options: [
        new GeneratedModels\PollOptionInput(
            text: 'Amsterdam, The Netherlands',
            custom: (object)[
                'country' => 'Netherlands',
                'timezone' => 'CET'
            ]
        ),
        new GeneratedModels\PollOptionInput(
            text: 'Boulder, CO',
            custom: (object)[
                'country' => 'United States',
                'timezone' => 'MST'
            ]
        )
    ]
);

$pollResponse = $client->createPoll($pollRequest);
```

</codetabs-item>

</codetabs>

The total size of all custom properties on a poll cannot exceed 5KB.

## Casting a Vote

Once a poll has been sent as part of an activity (and as long as the poll isn't closed for voting), votes can be cast.

### Send Vote on Option

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let activity = client.activity(
    for: "activity_123",
    in: FeedId(group: "user", id: "test")
)

let votes = try await activity.castPollVote(
    request: .init(
        vote: .init(optionId: "option_789")
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val activity = client.activity(
    activityId = "activity_123",
    fid = FeedId(group = "user", id = "test")
)

val votes: Result<PollVoteData?> = activity.castPollVote(
    request = CastPollVoteRequest(
        vote = VoteData(optionId = "option_789")
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    option_id: "option_789",
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    option_id: "option_789",
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    option_id: "option_789",
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final activity = client.activity(
  activityId: 'activity_123',
  fid: const FeedId(group: 'user', id: 'test'),
);

final votes = await activity.castPollVote(
  const CastPollVoteRequest(vote: VoteData(optionId: 'option_789')),
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.feeds.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  user_id: "<user id>",
  vote: {
    option_id: "option_789",
  },
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.Feeds().CastPollVote(ctx, "activity_123", "poll_456", &getstream.CastPollVoteRequest{
  UserID: getstream.PtrTo("john"),
  Vote: &getstream.VoteData{
    OptionID: getstream.PtrTo("option_789"),
  },
})
if err != nil {
  log.Fatal(err)
}
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# Cast a vote on an option
vote_request = GetStream::Generated::Models::CastPollVoteRequest.new(
  user_id: 'user123',
  vote: GetStream::Generated::Models::VoteData.new(
    option_id: 'option_789'
  )
)

response = client.feeds.cast_poll_vote('activity_123', 'poll_456', vote_request)

# Cast a vote with an answer (if answers are allowed)
answer_vote_request = GetStream::Generated::Models::CastPollVoteRequest.new(
  user_id: 'user123',
  vote: GetStream::Generated::Models::VoteData.new(
    answer_text: "Let's go somewhere else"
  )
)

response = client.feeds.cast_poll_vote('activity_123', 'poll_456', answer_vote_request)
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$pollResponse = $client->createPoll($pollRequest);
$pollData = $pollResponse->getData();
$pollId = $pollData->poll->id;
$pollOptionId = $pollData->poll->options[0]->id;
$activityId = $activityData->activity->id;

// Cast a vote on an option
$voteRequest = new GeneratedModels\CastPollVoteRequest(
    userID: 'user123',
    vote: new GeneratedModels\VoteData(optionID: $pollOptionId)
);

$response = $feedsClient->castPollVote($activityId, $pollId, $voteRequest);
```

</codetabs-item>

</codetabs>

### Send an Answer (if answers are configured to be allowed)

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let votes = try await activity.castPollVote(
    request: .init(
        vote: .init(answerText: "Let's go somewhere else")
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val votes: Result<PollVoteData?> = activity.castPollVote(
    request = CastPollVoteRequest(
        vote = VoteData(answerText = "Let's go somewhere else")
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    answer_text: `Let's go somewhere else`,
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    answer_text: `Let's go somewhere else`,
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote: {
    answer_text: `Let's go somewhere else`,
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final votes = await activity.castPollVote(
  const CastPollVoteRequest(
    vote: VoteData(answerText: "Let's go somewhere else"),
  ),
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.feeds.castPollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  user_id: "<user id>",
  vote: {
    answer_text: `Let's go somewhere else`,
  },
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.Feeds().CastPollVote(ctx, "activity_123", "poll_456", &getstream.CastPollVoteRequest{
  UserID: getstream.PtrTo("john"),
  Vote: &getstream.VoteData{
    AnswerText: getstream.PtrTo("Let's go somewhere else"),
  },
})
if err != nil {
  log.Fatal(err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$voteRequest = new GeneratedModels\CastPollVoteRequest(
    userID: 'user123',
    vote: new GeneratedModels\VoteData(answerText: "Let's go somewhere else")
);

$response = $feedsClient->castPollVote('activity_123', 'poll_456', $voteRequest);
```

</codetabs-item>

</codetabs>

### Important Notes

- If `enforceUniqueVotes` is set to **true** on poll, then any vote casted on option will replace the previous vote. Also this API will broadcast an event:
  - `poll.vote_changed` if `enforceUniqueVotes` is **true**
  - Otherwise `poll.vote_casted` event will be broadcasted
- Adding an answer will always replace the previous answer. This ensures that user can add maximum **1** answer (similar to what Polly app has)
- You need `CastVote` permission to be able to cast a vote
- API will return an error if poll is not attached to an activity.

### Overview of the vote model

<open-api-models modelname="PollVoteResponseData" recursive="false" headerlevel="4">
</open-api-models>

## Removing a Vote

A vote can be removed as well:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
try await activity.deletePollVote(voteId: "vote_789")
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
activity.deletePollVote(voteId = "vote_789")
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.deletePollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote_id: "vote_789",
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.deletePollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote_id: "vote_789",
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.deletePollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote_id: "vote_789",
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final votes = await activity.deletePollVote(voteId: 'vote_789');
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.feeds.deletePollVote({
  activity_id: "activity_123",
  poll_id: "poll_456",
  vote_id: "vote_789",
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
_, err = client.Feeds().DeletePollVote(context.Background(), "activity_123", "poll_456", "vote_789", &getstream.DeletePollVoteRequest{
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal(err)
}
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# Remove a vote
response = client.feeds.delete_poll_vote('activity_123', 'poll_456', 'vote_789', 'user123')
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
// Remove a vote
$response = $feedsClient->deletePollVote('activity_123', 'poll_456', 'vote_789', 'user123');
```

</codetabs-item>

</codetabs>

## Closing a Poll

If you want to prevent any further votes on a poll, you can close a poll for voting:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
try await activity.closePoll()
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
activity.closePoll()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.closePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.closePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.closePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final poll = await activity.closePoll();
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.updatePollPartial({
  poll_id: "poll_456",
  set: {
    is_closed: true,
  },
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# Close a poll for voting
update_request = GetStream::Generated::Models::UpdatePollPartialRequest.new(
  user_id: 'user123',
  set: {
    is_closed: true
  }
)

response = client.common.update_poll_partial('poll_456', update_request)
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
// Close a poll for voting
$updateRequest = new GeneratedModels\UpdatePollPartialRequest(
    userID: 'user123',
    set: (object)[
        'is_closed' => true
    ]
);

$response = $client->updatePollPartial('poll_456', $updateRequest);
```

</codetabs-item>

</codetabs>

## Retrieving a Poll

If you know the id of a poll you can easily retrieve the poll by using the `getPoll` method. If you don't know the id or if you want to retrieve multiple polls, use the query polls method (see below):

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let poll = try await activity.getPoll(userId: "john")
// userId is optional and can be provided for serverside calls
// in case you want to include the votes for the user
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val poll: Result<PollData> = activity.getPoll(userId = "john")
// userId is optional and can be provided for serverside calls
// in case you want to include the votes for the user
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const poll = client.pollFromState(activity.poll?.id!);
const unsubscribe = poll?.state.subscribe((state) => {
  // Called every time the poll state changes
  console.log(state);
});

// Call unsubscribe when you no longer want/need state updates
unsubscribe?.();
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
import { useCallback } from "react";

const poll = client.pollFromState(activity.poll?.id);

const selector = useCallback((state) => state ?? {}, []);

const state = useStateStore(poll?.state, selector);
// Called every time the poll state changes
console.log(state);
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
import { useCallback } from "react";

const poll = client.pollFromState(activity.poll?.id);

const selector = useCallback((state) => state ?? {}, []);

const state = useStateStore(poll?.state, selector);
// Called every time the poll state changes
console.log(state);
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final poll = await activity.getPoll();
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const response = await feed.getOrCreate({ user_id: "<user id>" });

console.log(response.activities[0].poll);

// or use poll id
const response = await client.getPoll({
  poll_id: "<poll id>",
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()
feed := client.Feeds().Feed("user", "john")
response, err := feed.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error getting feed:", err)
}

pollID := response.Data.Activities[1].Poll.ID

_, err = client.GetPoll(ctx, pollID, &getstream.GetPollRequest{
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error getting poll:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
// Get poll from feed
$response = $feedsClient->feed('user', 'user123')->getOrCreateFeed(
    new GeneratedModels\GetOrCreateFeedRequest(userID: 'user123')
);
$poll = $response->getData()->activities[0]->poll;

echo json_encode($poll);

// Or use poll id directly
$response = $client->getPoll($pollId, 'user123');
```

</codetabs-item>

</codetabs>

## Updating a Poll

There are two ways to update a poll: a **full** poll update and a **partial** update.

### Full Update

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let updatedPoll = try await activity.updatePoll(
    request: .init(
        id: "poll_456",
        name: "Where should we not go to?",
        options: [
            PollOptionRequest(
                custom: ["reason": "too expensive"],
                id: "option_789",
                text: "Amsterdam, The Netherlands"
            ),
            PollOptionRequest(
                custom: ["reason": "too far"],
                id: "option_790",
                text: "Boulder, CO"
            )
        ]
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val request = UpdatePollRequest(
    id = "poll_456",
    name = "Where should we not go to?",
    options = listOf(
        PollOptionRequest(
            custom = mapOf("reason" to "too expensive"),
            id = "option_789",
            text = "Amsterdam, The Netherlands"
        ),
        PollOptionRequest(
            custom = mapOf("reason" to "too far"),
            id = "option_790",
            text = "Boulder, CO"
        )
    )
)
val updatedPoll: Result<PollData> = activity.updatePoll(
    request = request
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.updatePoll({
  id: "poll_456",
  name: "Where should we host our next company event?",
  options: [
    {
      id: "option_789",
      text: "Amsterdam, The Netherlands",
      custom: {
        reason: "too expensive",
      },
    },
    {
      id: "option_123",
      text: "Boulder, CO",
      custom: {
        reason: "too far",
      },
    },
  ],
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.updatePoll({
  id: "poll_456",
  name: "Where should we host our next company event?",
  options: [
    {
      id: "option_789",
      text: "Amsterdam, The Netherlands",
      custom: {
        reason: "too expensive",
      },
    },
    {
      id: "option_123",
      text: "Boulder, CO",
      custom: {
        reason: "too far",
      },
    },
  ],
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.updatePoll({
  id: "poll_456",
  name: "Where should we host our next company event?",
  options: [
    {
      id: "option_789",
      text: "Amsterdam, The Netherlands",
      custom: {
        reason: "too expensive",
      },
    },
    {
      id: "option_123",
      text: "Boulder, CO",
      custom: {
        reason: "too far",
      },
    },
  ],
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
  final updatedPoll = await activity.updatePoll(
    const UpdatePollRequest(
      id: 'poll_456',
      name: 'Where should we not go to?',
      options: [
        PollOptionRequest(
          custom: {'reason': 'too expensive'},
          id: 'option_789',
          text: 'Amsterdam, The Netherlands',
        ),
        PollOptionRequest(
          custom: {'reason': 'too far'},
          id: 'option_790',
          text: 'Boulder, CO',
        ),
      ],
    ),
  );
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.updatePoll({
  id: "poll_456",
  name: "Where should we host our next company event?",
  options: [
    {
      id: "option_789",
      text: "Amsterdam, The Netherlands",
      custom: {
        reason: "too expensive",
      },
    },
    {
      id: "option_123",
      text: "Boulder, CO",
      custom: {
        reason: "too far",
      },
    },
  ],
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.UpdatePoll(ctx, &getstream.UpdatePollRequest{
	ID:   "poll_456",
	Name: "Where should we host our next company event?",
	Options: []getstream.PollOptionRequest{
		{
			ID:   "option_789",
			Text: getstream.PtrTo("Amsterdam, The Netherlands"),
			Custom: map[string]any{
				"reason": "too expensive",
			},
		},
		{
			ID:   "option_123",
			Text: getstream.PtrTo("Boulder, CO"),
			Custom: map[string]any{
				"reason": "too far",
			},
		},
	},
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error updating poll:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$updateRequest = new GeneratedModels\UpdatePollRequest(
    id: $pollId,
    name: 'Where should we not go to?',
    userID: 'user123',
    options: [
        new GeneratedModels\PollOptionRequest(
            id: $pollOptionId,
            text: 'Amsterdam, The Netherlands',
            custom: (object)[
                'reason' => 'too expensive'
            ]
        ),
        new GeneratedModels\PollOptionRequest(
            id: $pollOption2Id,
            text: 'Boulder, CO',
            custom: (object)[
                'reason' => 'too far'
            ]
        )
    ]
);

$response = $client->updatePoll($updateRequest);
```

</codetabs-item>

</codetabs>

All the poll properties that are omitted in the update request will either be removed or set to their default values.

### Partial Update

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let updatedPoll = try await activity.updatePollPartial(
    request: .init(
        set: ["name": "Updated poll name"],
        unset: ["custom_property"]
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val updatedPoll = activity.updatePollPartial(
    request = UpdatePollPartialRequest(
        set = mapOf("name" to "Updated poll name"),
        unset = listOf("custom_property")
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.updatePollPartial({
  poll_id: "poll_456",
  set: {
    name: "Updated poll name",
    unset: ["custom"],
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.updatePollPartial({
  poll_id: "poll_456",
  set: {
    name: "Updated poll name",
    unset: ["custom"],
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.updatePollPartial({
  poll_id: "poll_456",
  set: {
    name: "Updated poll name",
    unset: ["custom"],
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final updatedPoll = await activity.updatePollPartial(
  const UpdatePollPartialRequest(
    set: {'name': 'Updated poll name'},
    unset: ['custom_property'],
  ),
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.updatePollPartial({
  poll_id: "poll_456",
  set: {
    name: "Updated poll name",
    unset: ["custom"],
  },
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.UpdatePollPartial(ctx, "poll_456", &getstream.UpdatePollPartialRequest{
	Set: map[string]any{
		"name": "Updated poll name",
	},
	Unset: []string{"custom"},
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error updating poll partial:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$updateRequest = new GeneratedModels\UpdatePollPartialRequest(
    userID: 'user123',
    set: (object)[
        'name' => 'Updated poll name'
    ],
    unset: ['custom']
);

$response = $client->updatePollPartial('poll_456', $updateRequest);
```

</codetabs-item>

</codetabs>

## Deleting a Poll

Deleting a poll removes the poll, its associated options as well as all the votes on that poll. Be aware that removing a poll can't be undone.

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
try await activity.deletePoll()
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
activity.deletePoll()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.deletePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.deletePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.deletePoll({
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final poll = await activity.deletePoll();
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.deletePoll({
  poll_id: "poll_456",
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.DeletePoll(ctx, "poll_456", &getstream.DeletePollRequest{
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error deleting poll:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$response = $client->deletePoll('poll_456', 'user123');
```

</codetabs-item>

</codetabs>

## Adding, Updating and Deleting Poll Options

Poll options can be added, updated or deleted after a poll has been created:

### Add Poll Option

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let pollOption = try await activity.createPollOption(
    request: .init(
        custom: ["added_by": "user_123"],
        text: "Another option"
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val pollOption = activity.createPollOption(
    request = CreatePollOptionRequest(
        custom = mapOf("added_by" to "user_123"),
        text = "Another option"
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.createPollOption({
  poll_id: "poll_456",
  text: "Another option",
  custom: {
    added_by: "user_123",
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.createPollOption({
  poll_id: "poll_456",
  text: "Another option",
  custom: {
    added_by: "user_123",
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.createPollOption({
  poll_id: "poll_456",
  text: "Another option",
  custom: {
    added_by: "user_123",
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final pollOption = await activity.createPollOption(
  const CreatePollOptionRequest(
    custom: {'added_by': 'user_123'},
    text: 'Another option',
  ),
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.createPollOption({
    poll_id: 'poll_456',
    text: 'Another option',
    custom: {
        added_by: 'user_123'
    }
    user_id: 'user_123'
})
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.CreatePollOption(ctx, "poll_456", &getstream.CreatePollOptionRequest{
	Text:   "Another option",
	Custom: map[string]any{
		"added_by": "user_123",
	},
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error creating poll option:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$createRequest = new GeneratedModels\CreatePollOptionRequest(
    text: 'Another option',
    userID: 'user123',
    custom: (object)[
        'added_by' => 'user_123'
    ]
);

$response = $client->createPollOption($pollId, $createRequest);
```

</codetabs-item>

</codetabs>

If `allowUserSuggestedOptions` is set to `true` on poll, then user only needs `CastVote` permission to access this endpoint. Otherwise user needs `UpdatePoll` permission.

### Update Poll Option

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let updatedPollOption = try await activity.updatePollOption(
    request: .init(
        custom: ["my_custom_property": "my_custom_value"],
        id: "option_789",
        text: "Updated option"
    )
)
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val updatedPollOption = activity.updatePollOption(
    request = UpdatePollOptionRequest(
        custom = mapOf("my_custom_property" to "my_custom_value"),
        id = "option_789",
        text = "Updated option"
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.updatePollOption({
  poll_id: "poll_456",
  id: "option_123",
  text: "Updated option",
  custom: {
    my_custom_property: "my_custom_value",
  },
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.updatePollOption({
  poll_id: "poll_456",
  id: "option_123",
  text: "Updated option",
  custom: {
    my_custom_property: "my_custom_value",
  },
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.updatePollOption({
  poll_id: "poll_456",
  id: "option_123",
  text: "Updated option",
  custom: {
    my_custom_property: "my_custom_value",
  },
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final updatedPollOption = await activity.updatePollOption(
  const UpdatePollOptionRequest(
    custom: {'my_custom_property': 'my_custom_value'},
    id: 'option_789',
    text: 'Updated option',
  ),
);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.updatePollOption({
  poll_id: "poll_456",
  id: "option_123",
  text: "Updated option",
  custom: {
    my_custom_property: "my_custom_value",
  },
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.UpdatePollOption(ctx, "poll_456", &getstream.UpdatePollOptionRequest{
	ID:     "option_123",
	Text:   "Updated option",
	Custom: map[string]any{
		"my_custom_property": "my_custom_value",
	},
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error updating poll option:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$updateRequest = new GeneratedModels\UpdatePollOptionRequest(
    id: 'option_123',
    text: 'Updated option',
    userID: 'user123',
    custom: (object)[
        'my_custom_property' => 'my_custom_value'
    ]
);

$response = $client->updatePollOption('poll_456', $updateRequest);
```

</codetabs-item>

</codetabs>

### Delete Poll Option

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
try await activity.deletePollOption(optionId: "option_789")
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
activity.deletePollOption(optionId = "option_789")
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.deletePollOption({
  poll_id: "poll_456",
  option_id: "option_789",
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
await client.deletePollOption({
  poll_id: "poll_456",
  option_id: "option_789",
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
await client.deletePollOption({
  poll_id: "poll_456",
  option_id: "option_789",
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
final pollOption = await activity.deletePollOption(optionId: 'option_789');
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.deletePollOption({
  poll_id: "poll_456",
  option_id: "option_789",
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
_, err = client.DeletePollOption(context.Background(), "poll_456", "option_789", &getstream.DeletePollOptionRequest{
  UserID:   getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error deleting poll option:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$response = $client->deletePollOption($pollId, $pollOptionId, 'user123');
```

</codetabs-item>

</codetabs>

## Querying Votes

You are able to query the votes on a poll:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Retrieve all votes on either option1Id or option2Id
let pollVoteList = client.pollVoteList(
    for: .init(
        pollId: "poll_456",
        filter: .in(.optionId, ["option_789", "option_790"])
    )
)
let votesPage1 = try await pollVoteList.get()
let votesPage2 = try await pollVoteList.queryMorePollVotes()
let votesPage1And2 = pollVoteList.state.votes
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
// Retrieve all votes on either option1Id or option2Id
val pollVoteList = client.pollVoteList(
    query = PollVotesQuery(
        pollId = "poll_456",
        filter = PollVotesFilterField.optionId.`in`("option_789", "option_790")
    )
)
val votesPage1: Result<List<PollVoteData>> = pollVoteList.get()
val votesPage2: Result<List<PollVoteData>> = pollVoteList.queryMorePollVotes()
pollVoteList.state.votes.collect { votesPage1And2 ->
    // Handle votes list
}
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.queryPollVotes({
  filter: {
    option_id: { $in: ["option_789", "option_790"] },
  },
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.queryPollVotes({
  filter: {
    option_id: { $in: ["option_789", "option_790"] },
  },
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.queryPollVotes({
  filter: {
    option_id: { $in: ["option_789", "option_790"] },
  },
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
// Retrieve all votes on either option1Id or option2Id
final pollVoteList = client.pollVoteList(
  const PollVotesQuery(
    pollId: 'poll_456',
    filter: Filter.in_(
      PollVotesFilterField.optionId,
      ['option_789', 'option_790'],
    ),
  ),
);
final votesPage1 = await pollVoteList.get();
final votesPage2 = await pollVoteList.queryMorePollVotes();
final votesPage1And2 = pollVoteList.state.votes;
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.queryPollVotes({
  filter: {
    option_id: { $in: ["option_789", "option_790"] },
  },
  user_id: "<user id>",
  poll_id: "poll_456",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.QueryPollVotes(ctx, "poll_456", &getstream.QueryPollVotesRequest{
	Filter: map[string]any{
		"option_id": map[string]any{
			"$in": []string{"option_789", "option_790"},
		},
	},
	UserID: getstream.PtrTo("john"),
})
if err != nil {
	log.Fatal("Error querying poll votes:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$response = $client->queryPollVotes($pollId, 'user123', new GeneratedModels\QueryPollVotesRequest(
    filter: (object)[
        'option_id' => ['$in' => [$pollOptionId, $pollOption2Id]]
    ]
));
```

</codetabs-item>

</codetabs>

### Votes Queryable Built-In Fields

| Name         | Type                                              | Description                                      | Supported operators                 | Example                                                   |
| ------------ | ------------------------------------------------- | ------------------------------------------------ | ----------------------------------- | --------------------------------------------------------- |
| `id`         | String or list of strings                         | The ID of the vote                               | `$in`, `$eq`                        | `{ "id": { "$in": ["abcd", "defg"] } }`                   |
| `poll_id`    | string or list of strings                         | The ID of the poll this vote belongs to          | `$in`, `$eq`                        | `{ poll_id: { $eq: 'poll_123' } }`                        |
| `user_id`    | String or list of strings                         | The ID of the user who casted the vote           | `$in`, `$eq`                        | `{ "user_id": { "$eq": "abcd" } }`                        |
| `created_at` | String, must be formatted as an RFC3339 timestamp | The time the vote was created                    | `$eq`, `$gt`, `$lt`, `$gte`, `$lte` | `{ "created_at": { "$gte": "2023-12-04T09:30:20.45Z" } }` |
| `updated_at` | string, must be formatted as an RFC3339 timestamp | The time the vote was last updated               | `$eq`, `$gt`, `$lt`, `$gte`, `$lte` | `{ updated_at: { $gte: '2023-12-04T09:30:20.45Z' } }`     |
| `is_answer`  | Boolean                                           | Whether or not the vote is suggested by the user | `$eq`                               | `{ "is_answer": { "$eq": true } }`                        |
| `option_id`  | String or list of strings                         | The ID of the option the vote was casted on      | `$in`, `$eq`, `$exists`             | `{ "option_id": { "$in": ["abcd", "defg"] } }`            |

## Querying Polls

It is also possible to query for polls based on certain filter criteria:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Retrieve all polls that are closed for voting sorted by created_at
let pollList = client.pollList(
    for: .init(
        filter: .equal(.isClosed, true)
    )
)
let pollsPage1 = try await pollList.get()
let pollsPage2 = try await pollList.queryMorePolls()
let pollsPage1And2 = pollList.state.polls
```

</codetabs-item>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
// Retrieve all polls that are closed for voting sorted by created_at
val pollList = client.pollList(
    query = PollsQuery(
        filter = PollsFilterField.isClosed.equal(true)
    )
)
val pollsPage1: Result<List<PollData>> = pollList.get()
val pollsPage2: Result<List<PollData>> = pollList.queryMorePolls()
val pollsPage1And2 = pollList.state.polls
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
client.queryPolls({
  filter: {
    is_closed: true,
  },
  sort: [{ field: "created_at", direction: -1 }],
});
```

</codetabs-item>

<codetabs-item value="react" label="React">

```js
client.queryPolls({
  filter: {
    is_closed: true,
  },
  sort: [{ field: "created_at", direction: -1 }],
});
```

</codetabs-item>

<codetabs-item value="reactnative" label="React Native">

```js
client.queryPolls({
  filter: {
    is_closed: true,
  },
  sort: [{ field: "created_at", direction: -1 }],
});
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
// Retrieve all polls that are closed for voting sorted by created_at
final pollList = client.pollList(
  const PollsQuery(
    filter: Filter.equal(PollsFilterField.isClosed, true),
  ),
);
final pollsPage1 = await pollList.get();
final pollsPage2 = await pollList.queryMorePolls();
final pollsPage1And2 = pollList.state.polls;
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
client.queryPolls({
  filter: {
    is_closed: true,
  },
  sort: [{ field: "created_at", direction: -1 }],
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
ctx := context.Background()

_, err = client.QueryPolls(ctx, &getstream.QueryPollsRequest{
  Filter: map[string]any{
    "is_closed": true,
  },
  Sort: []getstream.SortParamRequest{
    {
      Field:     getstream.PtrTo("created_at"),
      Direction: getstream.PtrTo(-1),
    },
  },
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error querying polls:", err)
}
```

</codetabs-item>

<codetabs-item value="php" label="php">

```php
$response = $client->queryPolls('user123', new GeneratedModels\QueryPollsRequest(
    filter: (object)[
        'is_closed' => true
    ],
    sort: [
        ['field' => 'created_at', 'direction' => -1]
    ]
));
```

</codetabs-item>

</codetabs>

### Poll Queryable Built-In Fields

| Name                           | Type                                              | Description                                              | Supported operations                       | Example                                                   |
| ------------------------------ | ------------------------------------------------- | -------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------- |
| `id`                           | String or list of strings                         | The ID of the poll                                       | `$in`, `$eq`                               | `{ "id": { "$in": ["abcd", "defg"] } }`                   |
| `name`                         | String or list of strings                         | The name of the poll                                     | `$in`, `$eq`                               | `{ "name": { "$eq": "abcd" } }`                           |
| `voting_visibility`            | String                                            | Indicates whether the votes are casted anonymously       | `$eq`                                      | `{ "voting_visibility": { "$eq": "anonymous" } }`         |
| `max_votes_allowed`            | Number                                            | The maximum amount of votes per user                     | `$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte` | `{ "max_votes_allowed": { "$gte": 5 } }`                  |
| `allow_user_suggested_options` | Boolean                                           | Indicates whether the poll allows user suggested options | `$eq`                                      | `{ "allow_user_suggested_options": { "$eq": false } }`    |
| `allow_answers`                | Boolean                                           | Indicates whether the poll allows user answers           | `$eq`                                      | `{ "allow_answers": { "$eq": false } }`                   |
| `is_closed`                    | Boolean                                           | Indicates whether the poll is closed for voting          | `$eq`                                      | `{ "is_closed": { "$eq": true } }`                        |
| `created_at`                   | String, must be formatted as an RFC3339 timestamp | The time the poll was created                            | `$eq`, `$gt`, `$lt`, `$gte`, `$lte`        | `{ "created_at": { "$gte": "2023-12-04T09:30:20.45Z" } }` |
| `updated_at`                   | String, must be formatted as an RFC3339 timestamp | The time the poll was updated                            | `$eq`, `$gt`, `$lt`, `$gte`, `$lte`        | `{ "updated_at": { "$gte": "2023-12-04T09:30:20.45Z" } }` |
| `created_by_id`                | String or list of strings                         | The ID of the user who created the poll                  | `$in`, `$eq`                               | `{ "created_by_id": { "$in": ["abcd", "defg"] } }`        |

## Events

The following websocket events will be emitted:

- `feeds.poll.updated` whenever a poll (or its options) gets updated.
- `feeds.poll.closed` whenever a poll is closed for voting.
- `feeds.poll.deleted` whenever a poll gets deleted.
- `feeds.poll.vote_casted` whenever a vote is casted.
- `feeds.poll.vote_removed` whenever a vote is removed.
- `feeds.poll.vote_changed` whenever a vote is changed (case of enforce_unique_vote as true)


---

This page was last updated at 2026-03-05T19:00:56.078Z.

For the most recent version of this documentation, visit [https://getstream.io/activity-feeds/docs/javascript/polls/](https://getstream.io/activity-feeds/docs/javascript/polls/).