Skip to content


Subversion checkout URL

You can clone with
Download ZIP
An elegantly simple todo list
Ruby JavaScript
Branch: master


Fluttrly is a simple to-do list that allows you and others to add to a todo list for all to see!


At the home screen, just add your name to the text box and you're ready to start adding to a list.


Fluttrly is protected under the AGPL license.

Please see LICENSE for more details.


Lovingly created by Chris Oliver.


The Fluttrly API is ridiculously simple. Just append ".json" or ".xml" to the end of the list URL that you would like to retrieve.


Example: GET Request

Result: [{"task":{"name":"Example","created_at":"2010-12-19T02:58:06Z","completed":false,"updated_at":"2010-12-19T02:58:06Z","id":446,"content":"And you can easily share from the web"}}, {"task":{"name":"Example","created_at":"2010-12-19T02:57:58Z","completed":true,"updated_at":"2010-12-19T02:58:00Z","id":445,"content":"This is a completed task"}}, {"task":{"name":"Example","created_at":"2010-12-19T02:57:37Z","completed":false,"updated_at":"2010-12-19T02:57:51Z","id":443,"content":"Items can be checked as completed"}}, {"task":{"name":"Example","created_at":"2010-12-19T02:57:22Z","completed":false,"updated_at":"2010-12-19T02:57:22Z","id":440,"content":"Type a new task"}}]


Example: GET Request

Result: <?xml version="1.0" encoding="UTF-8"?> Example 2010-12-19T02:58:06Z false 2010-12-19T02:58:06Z 446 And you can easily share from the web Example 2010-12-19T02:57:58Z true 2010-12-19T02:58:00Z 445 This is a completed task Example 2010-12-19T02:57:37Z false 2010-12-19T02:57:51Z 443 Items can be checked as completed Example 2010-12-19T02:57:22Z false 2010-12-19T02:57:22Z 440 Type a new task


Posting a new task is easy too! Request a normal page to retrieve the authenticity_token, then you can submit the name of the list the task is for as well as the content of the task.

Example (Python):

#!/usr/bin/env python
# This example assumes you have a copy of Fluttr running on localhost:3000

import cookielib
import re
import urllib, urllib2

# Build the URL opener that saves cookies
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

# Request the test page so that we can get the auth token
f ="http://localhost:3000/test")
data =

# Parse out the auth token
auth_token ='name="authenticity_token".*value="(.+)"', data).group(1)

# Setup the POST request and encode it
data = {"authenticity_token": auth_token,
        "task[name]": "test",
        "task[content]": "This is a test",
data = urllib.urlencode(data)

f ="http://localhost:3000/tasks.js", data)

# You're done! Now visiting /test will have your new task!

Example (Ruby):

require 'net/http'
require 'uri'

# Initialize our session
url = URI.parse("http://localhost:3000/test")
req =
res = Net::HTTP.start(, url.port) { |http| http.request(req) }

# Parse out the auth token and get the session cookie
auth_token = $1 if res.body =~ /"authenticity_token".*value="(.+)"/ or nil
cookie = res['set-cookie'].split("; ")[0]

raise "No auth token" if auth_token.nil?

# Setup the params for POST
params = { 
    "task[content]" => "NICE", 
    "task[name]" => "test", 
    "authenticity_token" => auth_token

# Create a POST request
url = URI.parse("http://localhost:3000/tasks.js")
req =

# Setup parameters
req.add_field("Cookie", cookie)

res = Net::HTTP.start(, url.port) { |http| http.request(req) }
Something went wrong with that request. Please try again.