Pikatopikato.
Developers

Build scheduling into your product

Pikato is API-first. Everything the app does is available over a documented REST API — so you can automate polls, wire results into your own tools, and react to responses in real time.


Everything the UI does, programmatically

Create polls, add time slots, submit responses and read the full results matrix over a clean REST API. Anything you can do by hand, you can automate.

Results you can act on

Fetch the aggregated Yes/Maybe/No matrix per slot, find the winning time, and export any event as an ICS calendar file straight from the API.

Real-time webhooks

Subscribe to events — new responses, finalised times — and receive HMAC-signed, timestamped callbacks so your systems react the moment something changes. No polling required.

Scoped API keys

Issue and revoke tokens with fine-grained abilities (events:read, events:write, responses:read, webhooks:manage). Grant each integration only what it needs.

OAuth2 for third parties

Build apps on behalf of other accounts with the client-credentials grant. Exchange credentials at POST /oauth/token and scope the resulting token to exactly the access you need.

Safe to retry

Idempotency keys make write requests safe to repeat — a dropped connection or a retry never creates a duplicate poll or response.


Quick examples

List your active polls

Fetch your saved polls and keep the ones still collecting responses (status "open"). Needs an API key with the events:read ability.

const API = 'https://your-domain.example/api/v1';
const TOKEN = 'pk_live_…'; // API key with events:read

const res = await fetch(`${API}/account/events`, {
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
const { data } = await res.json();

// Keep only polls still open for responses (the other status is "finalized").
const active = data.filter((poll) => poll.status === 'open');

active.forEach((poll) => {
  console.log(poll.id, poll.title, `${poll.participant_count} responses`);
});

Read who answered and what they picked

Fetch the participant × slot matrix for one poll and list each person’s name with their Yes / Maybe / No choice per time slot. Needs the responses:read ability.

const API = 'https://your-domain.example/api/v1';
const TOKEN = 'pk_live_…'; // API key with responses:read
const eventId = 'evt_…';

const res = await fetch(`${API}/events/${eventId}/responses`, {
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
const { data } = await res.json();

// Map slot id -> readable label so answers aren't just ids.
const slotLabel = Object.fromEntries(
  data.slots.map((s) => [s.id, s.starts_at ?? s.location ?? s.id]),
);

// One row per participant: their name and their choice for each slot.
data.participants.forEach((p) => {
  const choices = Object.entries(p.answers)
    .map(([slotId, value]) => `${slotLabel[slotId]}: ${value}`)
    .join(', ');
  console.log(`${p.display_name} → ${choices}`);
});

Authenticate every request with a Bearer API key from your account. Full endpoint reference — including pagination cursors and error shapes — is in the API documentation ↗.


Free tier

1,000 API calls / month · 60 requests / minute, unlimited polls, 10 saved in your account, plus webhooks and scoped keys. Above that allowance you need a subscription. Email invitations are billed separately in credits.