Connect Doodle to Lovable by creating an Edge Function that calls Doodle's REST API with an API key stored in Cloud Secrets. Build group availability polling tools, meeting time optimization features, and participant scheduling UIs. Doodle differs from Calendly and Acuity — it finds the best time for multiple participants rather than booking 1:1 appointments against one person's calendar.
Build Group Meeting Coordination Tools with Doodle in Lovable
Doodle solves a specific and common problem: when multiple people need to meet, finding a time that works for everyone is painful without a systematic approach. Doodle's poll model asks each participant to mark which proposed times work for them, then surfaces the option with the most availability. This is fundamentally different from Calendly or Acuity, which are for one host to let others book into available slots on their calendar.
Lovable can integrate Doodle to build meeting coordination features directly into your app. Common scenarios include: a team management app that creates availability polls for team retrospectives, a hiring platform that coordinates interview schedules with multiple interviewers, an event planning tool that finds the best date for a group gathering, or a client portal that proposes meeting times and lets clients indicate availability without leaving the app.
Doodle's API lets you create polls with proposed time options, share poll links with participants, retrieve participant responses, and determine the optimal meeting time based on availability data. By building the polling interface into Lovable rather than directing users to Doodle's website, you create a seamless experience that keeps users within your app's flow while leveraging Doodle's group scheduling logic.
Integration method
Doodle connects to Lovable through an Edge Function that calls Doodle's REST API with an API key stored in Cloud Secrets. The Edge Function creates polls, manages participants, retrieves availability responses, and determines the optimal meeting time based on participant votes.
Prerequisites
- A Lovable account with a project open and Lovable Cloud enabled
- A Doodle account with API access enabled (available on Business or Enterprise plans)
- A Doodle API key from your account's API settings
- A clear use case for group scheduling — Doodle is designed for multi-participant availability finding, not 1:1 booking
- Understanding of Doodle's poll model — proposing time options and collecting availability votes from participants
Step-by-step guide
Get Your Doodle API Key
Get Your Doodle API Key
Doodle's API access is available on Business and Enterprise plans. Log in to your Doodle account and navigate to Account Settings → API or look for an 'Integrations' section in your account dashboard. Doodle's API access and key generation location may vary based on your plan and account type. If you're using Doodle's current API (v2), navigate to the developer settings in your account and create an API key. The key is a static credential you include in requests. For some Doodle plan tiers, you may need to contact Doodle support to enable API access. Doodle's API base URL is https://api.doodle.com/v2 and authentication uses the X-API-Key header or a Bearer token depending on the API version. Review the current Doodle API documentation at developer.doodle.com for the exact authentication method, as Doodle has iterated on their API over time. Note that Doodle also provides a publicly accessible URL for each poll at doodle.com/poll/{pollId} — users without Doodle accounts can participate in polls through this URL. Your Lovable app can generate these links after creating polls via the API and share them with participants who will respond through Doodle's website rather than your custom UI.
Pro tip: If your organization uses Doodle for significant meeting coordination, the Business plan's API access is worth the investment. The API enables automation that saves hours of scheduling coordination weekly. Contact Doodle sales at doodle.com/enterprise for API-focused plan discussions.
Expected result: You have a Doodle API key and have verified that API access is enabled on your account. You can test the key by calling the Doodle API from your browser's developer tools.
Store Doodle API Key in Cloud Secrets
Store Doodle API Key in Cloud Secrets
In Lovable, click the '+' button next to the Preview panel to open the Cloud tab, then navigate to Secrets. Add: - DOODLE_API_KEY: your Doodle API key Doodle's authentication is straightforward — a single API key in a request header. No OAuth token exchange or credential combination is needed. The Edge Function adds 'X-API-Key: {key}' (or 'Authorization: Bearer {key}' depending on your Doodle API version) to every Doodle API request. Verify the correct header format from Doodle's API documentation for your account's API version. Doodle has changed their authentication mechanism between API versions. The current v2 API typically uses the X-API-Key header, but confirm this from the documentation you receive when API access is enabled on your account.
Pro tip: Doodle polls are publicly visible via their doodle.com/poll/{id} URL — anyone with the link can participate. This is by design for group scheduling. For sensitive meetings (executive discussions, confidential interviews), use Doodle's privacy settings or ensure you're only sharing poll links with intended participants.
Expected result: DOODLE_API_KEY is stored in Cloud Secrets and accessible via Deno.env.get() in Edge Functions.
Create the Doodle API Edge Function
Create the Doodle API Edge Function
Create the Edge Function that handles Doodle poll operations. The core workflow involves: creating a poll with a title, description, and proposed time options; retrieving a poll's current state and all participant responses; and determining the optimal time slot based on availability data. Doodle's poll creation endpoint accepts: title (required), description (optional), options (array of datetime strings representing the proposed meeting times), and settings (object for poll configuration like whether participants need to provide a name, whether it's hidden, etc.). The poll response structure shows each participant's availability for each time option: typically available, not_available, or if_need_be (if supported). The Edge Function can calculate the optimal slot by finding the option with the highest count of 'available' responses. The poll sharing URL format is typically: https://doodle.com/poll/{pollId} — your Edge Function should return this URL after creating a poll so users can share it with participants who will respond through Doodle's website.
Create an Edge Function called doodle-proxy at supabase/functions/doodle-proxy/index.ts. Read DOODLE_API_KEY from Deno environment variables. Accept POST requests with: operation (createPoll, getPoll, getParticipants, findBestSlot), and operation-specific params (for createPoll: title, description, options array of ISO datetime strings, duration in minutes; for getPoll/getParticipants/findBestSlot: pollId). For createPoll, POST to https://api.doodle.com/v2/polls with X-API-Key header. For getPoll, GET the poll details. For getParticipants, GET participant responses. For findBestSlot, analyze participant availability and return the option with the most 'available' votes and a participant availability matrix. Include CORS headers and error handling.
Paste this in Lovable chat
1// supabase/functions/doodle-proxy/index.ts2import { serve } from "https://deno.land/std@0.168.0/http/server.ts";34const corsHeaders = {5 "Access-Control-Allow-Origin": "*",6 "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",7 "Access-Control-Allow-Methods": "POST, OPTIONS",8};910serve(async (req: Request) => {11 if (req.method === "OPTIONS") {12 return new Response("ok", { headers: corsHeaders });13 }1415 try {16 const apiKey = Deno.env.get("DOODLE_API_KEY");17 const headers = { "X-API-Key": apiKey || "", "Content-Type": "application/json", "Accept": "application/json" };1819 const { operation, ...params } = await req.json();20 let data;2122 if (operation === "createPoll") {23 const response = await fetch("https://api.doodle.com/v2/polls", {24 method: "POST",25 headers,26 body: JSON.stringify({27 title: params.title,28 description: params.description,29 options: params.options.map((dt: string) => ({ start: dt })),30 settings: { open: true },31 }),32 });33 const poll = await response.json();34 data = { pollId: poll.id, pollUrl: `https://doodle.com/poll/${poll.id}`, poll };35 } else if (operation === "getPoll") {36 const response = await fetch(`https://api.doodle.com/v2/polls/${params.pollId}`, { headers });37 data = await response.json();38 } else if (operation === "getParticipants") {39 const response = await fetch(`https://api.doodle.com/v2/polls/${params.pollId}/participants`, { headers });40 data = await response.json();41 } else if (operation === "findBestSlot") {42 const [pollRes, partRes] = await Promise.all([43 fetch(`https://api.doodle.com/v2/polls/${params.pollId}`, { headers }),44 fetch(`https://api.doodle.com/v2/polls/${params.pollId}/participants`, { headers }),45 ]);46 const poll = await pollRes.json();47 const participants = await partRes.json();48 // Count available votes per option49 const voteCounts = (poll.options || []).map((opt: { start: string }, idx: number) => ({50 option: opt,51 index: idx,52 availableCount: (participants.participants || []).filter((p: { availability: string[] }) =>53 p.availability?.[idx] === "available"54 ).length,55 totalParticipants: (participants.participants || []).length,56 }));57 const best = voteCounts.sort((a: { availableCount: number }, b: { availableCount: number }) => b.availableCount - a.availableCount)[0];58 data = { bestOption: best, allOptions: voteCounts, participants: participants.participants };59 }6061 return new Response(JSON.stringify(data), { status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" } });62 } catch (error) {63 return new Response(JSON.stringify({ error: error.message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } });64 }65});Pro tip: Doodle's API response structure may differ between API versions. Test the createPoll response in Cloud → Logs and adjust the Edge Function's field access (poll.id, poll.options, participant.availability) to match your API version's actual response.
Expected result: The doodle-proxy Edge Function is deployed. Testing the createPoll operation creates a real Doodle poll and returns a poll ID and shareable URL.
Build the Poll Creation and Management UI
Build the Poll Creation and Management UI
With the Edge Function working, open Lovable chat and describe the meeting scheduling UI. For group scheduling, the most important UX decisions are: how users propose time options (a date-time picker for selecting multiple options), how participants indicate availability (inline in the app or via Doodle's public poll URL), and how the optimal time is surfaced. For proposing times, a multi-select date-time picker is the ideal UI. Users pick a date and then add time slots one by one. Each slot shows as a tag in the proposal list with an 'x' to remove it. A minimum of 3-5 options gives participants enough choices to find availability. For participant responses, you have two options: direct API integration (participants respond through your Lovable UI using the addParticipant API) or the Doodle public URL (participants click the link and respond on Doodle's website). The public URL approach requires less frontend development but takes participants out of your app. For seamless in-app experience, build the inline response UI. For displaying results, a matrix grid (participants as rows, time options as columns) with availability indicators is the standard Doodle-style display. Highlight the column with the most availability. For the 'findBestSlot' function, display the winning time prominently with a 'This time works for X of Y participants' badge.
Using the doodle-proxy Edge Function, build a group meeting scheduler. The create poll form should have: meeting title (required text), description (optional), and a time option selector where users pick multiple date-time combinations (minimum 3, maximum 8 options) using a date picker and time input. Show selected options as removable tags. On 'Create Poll', call createPoll and show a success state with: the shareable poll URL in a copyable input, a 'View Results' section that calls findBestSlot every 60 seconds and shows an availability matrix (participants as rows, time options as columns, green checkmarks for available, red X for not available), and a highlighted 'Best Time' card showing the winning option with participant count.
Paste this in Lovable chat
Pro tip: Format the time options for display in the user's local timezone. When displaying the availability matrix to participants in different time zones, show each time in their local zone. Use JavaScript's toLocaleString() with explicit timezone options for consistent formatting.
Expected result: Creating a poll through the Lovable UI generates a real Doodle poll with the specified time options. The shareable URL works when opened in a browser. The availability matrix updates as participants respond.
Add Participant Availability Collection and Best Time Selection
Add Participant Availability Collection and Best Time Selection
Once the poll is created and participants have responded (either through Doodle's public URL or a custom inline UI), the final step is surfacing the optimal meeting time and enabling the organizer to confirm it. The findBestSlot operation in the Edge Function calculates which time option has the most 'available' participants. Beyond the simple maximum, you may want to implement weighted scoring: give full weight to 'available' responses, partial weight to 'if_need_be' responses (if Doodle supports this in your API tier), and zero weight to 'not_available'. This helps identify the best slot even if no time is perfect for everyone. Once the organizer selects the final time, the Lovable app should: save the confirmed meeting time to Supabase, send calendar invites to participants (using a calendar service or the confirmed meeting details as plain text), and optionally update the Doodle poll status to closed. Store participant emails from the poll response so you can send notifications without requiring participants to re-enter their contact information. For enterprise group scheduling workflows with advanced routing logic, calendar system integration, or CRM-connected scheduling, RapidDev's team can help design the complete meeting orchestration layer.
Complete the group scheduling feature by adding a 'Confirm Meeting' flow. After the poll has responses, show the organizer a 'Best Times' ranking of the top 3 options with availability counts. Add a 'Confirm This Time' button for each option. When confirmed: save the meeting to a Supabase meetings table (id, poll_id, title, confirmed_time, participant_emails, created_at), show a confirmation modal with the meeting details and a calendar add link (Google Calendar add URL), and display a 'Meeting Confirmed' banner on the poll results page. Also add a 'Share Results' button that copies a shareable link showing the poll results.
Paste this in Lovable chat
Expected result: The organizer can confirm a meeting time from the poll results. The confirmed meeting is saved to Supabase. A calendar add link lets participants add the meeting to their calendars.
Common use cases
Build a team meeting scheduling tool embedded in a project management app
A project management Lovable app needs a feature for scheduling team retrospectives and standups. Rather than the team organizer manually sending Doodle links, the app creates a Doodle poll for the next sprint planning meeting, invites all project members automatically, and shows the polling results inline.
I'm building a project management app and want to add meeting scheduling. I've stored DOODLE_API_KEY in Cloud Secrets. Create an Edge Function called doodle-proxy that calls Doodle's API at https://api.doodle.com/v2 to: create a poll with a title, description, and array of proposed time slots (datetime strings), get a poll's details and participant responses, and find the time slot with the most 'available' responses. Then build a 'Schedule Meeting' modal where users enter a meeting title, select 4-5 proposed time options from a date-time picker, and the app creates a Doodle poll and displays a shareable link. Show poll results in a matrix with participants as rows and time slots as columns.
Copy this prompt to try it in Lovable
Automate interview scheduling with multi-interviewer availability polling
A hiring platform needs to coordinate interview schedules across multiple interviewers for each candidate. Creating a Doodle poll for each interview request lets all interviewers indicate their availability, and the platform automatically selects the time that works for everyone and sends calendar invites.
I'm building a hiring platform. When a candidate passes the resume screen, I need to schedule a panel interview with 3 interviewers. Using DOODLE_API_KEY from Cloud Secrets, create an Edge Function that: creates a Doodle poll titled '{CandidateName} - {JobTitle} Interview' with 8 proposed time slots over the next 5 business days (30-minute windows), returns the poll ID and invitation URL, and retrieves poll results showing which slots each interviewer marked as available. Build an interview scheduling page that creates the poll automatically when triggered, shows the hiring manager a link to send interviewers, and displays a real-time availability matrix updating as interviewers respond.
Copy this prompt to try it in Lovable
Create a client meeting proposer for a consulting app
A consulting firm's client portal needs to propose meeting times to clients for project reviews. The consultant creates a Doodle poll with proposed times, the client indicates availability directly in the Lovable portal, and the system notifies the consultant when a time is confirmed.
Build a meeting scheduler for my client portal. Consultants can propose 3-5 meeting times, which creates a Doodle poll. The client sees the poll inline in the portal and clicks 'Available' or 'Not available' for each time. When the client responds, the system picks the best available slot and shows a confirmation to both parties. Using DOODLE_API_KEY, create an Edge Function for poll creation, adding participant responses via the API, and retrieving current poll status. The poll UI should show times in the client's local timezone with a clean card-based layout instead of Doodle's default table.
Copy this prompt to try it in Lovable
Troubleshooting
Doodle API returns 401 Unauthorized when creating polls
Cause: The API key is invalid, the account plan does not include API access, or the authentication header format does not match the required format for your Doodle API version.
Solution: Verify your Doodle API key in the account settings. Check that your Doodle plan includes API access — the Business or Enterprise plan is typically required. Verify the correct header name for authentication: current Doodle v2 API uses X-API-Key, but some configurations use Authorization: Bearer. Check the API documentation provided with your API key for the exact header format.
createPoll returns 422 Unprocessable Entity with no clear error message
Cause: The poll options format is incorrect. Doodle expects time options in a specific format that may differ from standard ISO 8601.
Solution: Check the Doodle API documentation for the exact format of the options array. Doodle's API may expect objects with start and end properties, or just start properties for fixed-duration meetings. Try a minimal poll creation first: just a title and two simple time options, then expand to the full format once basic creation works.
1// Minimal Doodle poll creation for testing:2const testPollBody = {3 title: "Test Meeting",4 options: [5 { start: "2026-04-01T14:00:00Z" },6 { start: "2026-04-02T14:00:00Z" },7 ],8};Poll availability matrix shows all empty even though Doodle shows responses
Cause: The participant availability array indexing doesn't match the option order in the poll response, or the availability field name differs between Doodle API versions.
Solution: Log the raw participants response in Cloud → Logs to see the exact structure. Doodle's participant object may use different field names (availability vs votes vs slots). Match your Edge Function's field access to the actual response structure. The availability array maps position to the poll option at the same index — verify this ordering is consistent.
Doodle poll URL returned by the API does not work when opened in a browser
Cause: The poll URL format constructed from the poll ID may be incorrect, or the poll may not be publicly accessible due to privacy settings.
Solution: Verify the URL format for your Doodle account region — the standard URL is https://doodle.com/poll/{pollId} but some Doodle accounts use regional subdomains. Check the poll response object directly — Doodle API responses often include a share_url or url field with the correct public URL that you should use instead of constructing it from the poll ID.
1// Use the URL from the API response rather than constructing it:2const pollUrl = poll.share_url || poll.url || `https://doodle.com/poll/${poll.id}`;Best practices
- Propose at least 4-6 time options in each Doodle poll — more options increase the likelihood of finding a time that works for everyone
- Format all time options in UTC when sending to the Doodle API and convert to participant timezones for display in the results matrix
- Use Doodle's public poll URL for participants outside your Lovable app rather than building a custom response UI — Doodle's website is familiar and accessible without requiring participants to have accounts
- Poll for results every 60 seconds using setInterval rather than real-time WebSockets — Doodle does not provide webhook events for participant responses
- Store confirmed meeting data in Supabase when an organizer finalizes a time — this creates a permanent record independent of Doodle's data retention policies
- Display the availability matrix with clear visual differentiation between available, unavailable, and no-response states so organizers can quickly scan for consensus
- Limit poll duration — close polls after 48-72 hours for meeting coordination to maintain urgency and prevent indefinite scheduling delays
- Include participant email addresses in your Lovable app's meeting records so you can send calendar invites after confirming a time
Alternatives
Calendly is designed for 1:1 booking where one host sets availability and individual guests pick a time — choose it when one person is scheduling meetings rather than finding group consensus.
Acuity Scheduling is built for service businesses with intake forms and payment collection — choose it when you need appointment booking with client questionnaires rather than group availability finding.
ScheduleOnce is optimized for sales team scheduling with routing and round-robin logic — choose it for coordinating sales calls rather than general group meeting scheduling.
Frequently asked questions
Can participants respond to Doodle polls without having a Doodle account?
Yes. Doodle polls are publicly accessible via the poll URL (doodle.com/poll/{id}). Anyone with the link can add their name and mark availability without creating a Doodle account. This is one of Doodle's key advantages for external coordination — participants don't need to sign up to respond. When building your Lovable integration, share the Doodle poll URL for external participants and optionally build an inline response UI for internal users already in your app.
Does Doodle support automatic meeting scheduling when all participants respond?
Doodle does not automatically create calendar events when a poll closes — it only collects availability data and shows the winning time. The Lovable app is responsible for sending calendar invites after the organizer confirms the winning time. Build a confirmation step in your Lovable app that generates Google Calendar or Outlook calendar invite links using the selected time, and send these to participant emails collected from the poll responses.
How do I handle time zones in Doodle polls with international participants?
Store all poll times in UTC in the Doodle API. When displaying poll results in your Lovable app, convert each time to the current user's local timezone using JavaScript's Intl.DateTimeFormat API or a library like date-fns. When sharing the Doodle poll URL with participants, Doodle's website automatically shows times in each participant's browser timezone — one of the reasons the public poll URL is useful for international coordination.
Is there a limit to how many participants can respond to a Doodle poll?
Doodle's free plan limits polls to a certain number of responses (typically 10-20 participants), while Business and Enterprise plans support unlimited participants. For enterprise team scheduling with large groups, verify your plan's participant limits before building workflows that assume unlimited responses.
Can I build a fully custom Doodle-like availability poll without using Doodle's API?
Yes, you can build the same functionality directly in Lovable using Supabase. Create a polls table (poll ID, title, time options as JSONB) and a responses table (poll ID, participant name, participant email, availability per option). Build the response UI directly in Lovable. This gives you full control over the design, avoids Doodle API costs, and keeps all data in your Supabase. The tradeoff is that you maintain the polling logic rather than leveraging Doodle's infrastructure.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation