DEV Community

Alex Spinov
Alex Spinov

Posted on

Rallly Has a Free API — Heres How to Self-Host Meeting Scheduling Without Doodle

Rallly is a self-hosted scheduling tool — like Doodle but open source. Create polls, find the best meeting time, and integrate with your calendar.

Why Rallly?

  • Self-hosted: Your server, no tracking
  • No account needed: Participants vote without signing up
  • Beautiful UI: Modern, responsive design
  • API access: Programmatic poll management
  • Email notifications: Updates when participants vote
  • Time zones: Automatic timezone handling
  • Free: Completely open source

Self-Host

git clone https://github.com/lukevella/rallly.git
cd rallly

# Configure
cp .env.example .env
# Edit .env: set DATABASE_URL, SECRET_PASSWORD, NEXT_PUBLIC_BASE_URL

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000

Create a Poll

Through the UI:

  1. Enter title and description
  2. Add date/time options
  3. Share the link — no signup required

API: Create Poll

curl -X POST http://localhost:3000/api/polls \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{
    "title": "Team Standup Time",
    "description": "When should we have our daily standup?",
    "options": [
      {"startDate": "2026-04-01T09:00:00Z", "endDate": "2026-04-01T09:30:00Z"},
      {"startDate": "2026-04-01T10:00:00Z", "endDate": "2026-04-01T10:30:00Z"},
      {"startDate": "2026-04-01T14:00:00Z", "endDate": "2026-04-01T14:30:00Z"}
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

API: Get Poll Results

curl http://localhost:3000/api/polls/POLL_ID \
  -H 'Authorization: Bearer YOUR_TOKEN'
Enter fullscreen mode Exit fullscreen mode

Response includes all participants and their votes.

API: Add Participant Vote

curl -X POST http://localhost:3000/api/polls/POLL_ID/participants \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Alice",
    "votes": [
      {"optionId": "opt_1", "type": "yes"},
      {"optionId": "opt_2", "type": "ifNeedBe"},
      {"optionId": "opt_3", "type": "no"}
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

Integrate with Slack Bot

app.command('/schedule', async ({ command, ack, say }) => {
  await ack();

  const poll = await fetch('http://rallly:3000/api/polls', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer TOKEN' },
    body: JSON.stringify({
      title: command.text,
      options: generateNextWeekSlots(),
    }),
  }).then(r => r.json());

  await say(`Vote for the best time: ${poll.url}`);
});
Enter fullscreen mode Exit fullscreen mode

Docker Compose

services:
  rallly:
    image: lukevella/rallly:latest
    ports:
      - '3000:3000'
    environment:
      - DATABASE_URL=postgres://rallly:password@db:5432/rallly
      - SECRET_PASSWORD=your-secret
      - NEXT_PUBLIC_BASE_URL=https://schedule.example.com
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      - POSTGRES_USER=rallly
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=rallly
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A remote team of 20 replaced Doodle Premium ($50/year) with self-hosted Rallly. They schedule 15+ meetings per week, and participants don't need accounts. The API integration with their Slack bot means scheduling starts with /schedule Team Retrospective.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)