The data below was derived from Wireshark on the port where the Philips Hue base station sits.

There is a string 0123456789abdcef0123456789abcdef referred to in the below data. This is a username that the client uses when talking to the base station to identify itself. This username is generated by the client and sent to the base station via POST request.

If the LINK button on the base station has not been pressed, this POST request will result in an error being returned via JSON. Once the LINK button is pressed, the next POST request you make will save the username you sent to the client whitelist.

NEW CLIENT ASSOCIATION WITH BASE STATION

The client makes a GET request and is returned a JSON error message …

GET /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*

[
  {
    "error":
    {
      "type":1,
      "address":"/lights",
      "description":"unauthorized user"
    }
  }
]

The client then continually makes POST requests with a username that the client derives and a device type, but until the LINK button is pressed on the base station, an error message is returned.

POST /api HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 86
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"username":"0123456789abdcef0123456789abcdef","devicetype":"iPhone 5"}

[
  {
    "error":
    {
      "type":101,
      "address":"",
      "description":"link button not pressed"
    }
  }
]

After pushing the LINK button on the base station the POST request succeeds.

POST /api HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 86
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"username":"0123456789abdcef0123456789abcdef","devicetype":"iPhone 5"}

[
  {
    "success":
    {
      "username":"0123456789abdcef0123456789abcdef"
    }
  }
]

SHOW BULB AND BASE STATION CONFIGURATION

GET /api/0123456789abdcef0123456789abcdef HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*

{
  "lights":
  {
    "1":
    {
      "state":
      {
        "on":false,
        "bri":146,
        "hue":13234,
        "sat":208,
        "xy":[0.5090,0.4149],
        "ct":459,
        "alert":"none",
        "effect":"none",
        "colormode":"ct",
        "reachable":true
      },
      "type": "Extended color light",
      "name": "Living",
      "modelid": "LCT001",
      "swversion": "65003148",
      "pointsymbol":
      {
        "1":"none",
        "2":"none",
        "3":"none",
        "4":"none",
        "5":"none",
        "6":"none",
        "7":"none",
        "8":"none"
      }
    },
    "2":
    {
      "state":
      {
        "on":false,
        "bri":162,
        "hue":2213,
        "sat":238,
        "xy":[0.6349,0.3413],
        "ct":500,
        "alert":"none",
        "effect":"none",
        "colormode":"xy",
        "reachable":true
      },
      "type": "Extended color light",
      "name": "Bedroom Far",
      "modelid": "LCT001",
      "swversion": "65003148",
      "pointsymbol":
      {
        "1":"none",
        "2":"none",
        "3":"none",
        "4":"none",
        "5":"none",
        "6":"none",
        "7":"none",
        "8":"none"
      }
    },
    "3":
    {
      "state":
      {
        "on":false,
        "bri":146,
        "hue":13122,
        "sat":211,
        "xy":[0.3565,0.1775],
        "ct":462,
        "alert":"none",
        "effect":"none",
        "colormode":"ct",
        "reachable":true
      },
      "type": "Extended color light",
      "name": "Bedroom Near",
      "modelid": "LCT001",
      "swversion": "65003148",
      "pointsymbol":
      {
        "1":"none",
        "2":"none",
        "3":"none",
        "4":"none",
        "5":"none",
        "6":"none",
        "7":"none",
        "8":"none"
      }
    }
  },
  "groups": {},
  "config":
  {
    "name": "Philips hue",
    "mac": "00:17:88:09:26:9d",
    "dhcp": true,
    "ipaddress": "10.255.255.44",
    "netmask": "255.255.255.0",
    "gateway": "10.255.255.254",
    "proxyaddress": "",
    "proxyport": 0,
    "UTC": "2012-11-02T18:34:38",
    "whitelist":
    {
      "0123456789abdcef0123456789abcdef":
      {
        "last use date": "2012-11-02T18:34:38",
        "create date": "2012-11-01T21:04:48",
        "name": "iPhone 5"
      },
    },
    "swversion": "01003542",
    "swupdate":
    {
      "updatestate":0,
      "url":"",
      "text":"",
      "notify": false
    },
    "linkbutton": false,
    "portalservices": false
  },
  "schedules": {}
}

SHOW BASE STATION CONFIGURATION

GET /api/0123456789abdcef0123456789abcdef/config HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*

{
  "name": "Philips hue",
  "mac": "00:17:88:09:00:00",
  "dhcp": true,
  "ipaddress": "10.255.255.44",
  "netmask": "255.255.255.0",
  "gateway": "10.255.255.1",
  "proxyaddress": "",
  "proxyport": 0,
  "UTC": "2012-11-02T18:34:35",
  "whitelist":
  {
    "0123456789abdcef0123456789abcdef":
    {
      "last use date": "2012-11-02T18:34:35",
      "create date": "2012-11-01T21:04:48",
      "name": "iPhone 5"
    },
  },
  "swversion": "01003542",
  "swupdate":
  {
    "updatestate":0,
    "url":"",
    "text":"",
    "notify": false
  },
  "linkbutton": false,
  "portalservices": false
}

SHOW BULB NAMES

GET /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{
  "1":
  {
    "name": "Dining"
  },
  "2":
  {
    "name": "Bedroom Far"
  },
  "3":
  {
    "name": "Bedroom Near"
  }
}

SHOW BULB GROUPS

You can specify which group to show by changing the number in the URL.

For example /api/0123456789abdcef0123456789abcdef/groups/1 for group #1.

GET /api/0123456789abdcef0123456789abcdef/groups/0 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{
  "action":
  {
    "on":false,
    "bri":254,
    "hue":14922,
    "sat":144,
    "xy":[0.4595,0.4105],
    "ct":369,
    "effect":"none",
    "colormode":"ct"
  },
  "lights": ["1","2","3"],
  "name": "Lightset 0"
}

SHOW SCHEDULES

GET /api/0123456789abdcef0123456789abcdef/schedules HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{
  "1":
  {
    "name": "Timer on f 649863             "
  },
  "2":
  {
    "name": "Timer on 807548               "
  },
  "3":
  {
    "name": "Timer on f 996556             "
  },
  "4":
  {
    "name": "Timer on 208820               "
  },
}

CHANGE BASE STATION CONFIGURATION

PUT /api/0123456789abdcef0123456789abcdef/config HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 67
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"name":"New Name","proxyaddress":" ","proxyport":0,"dhcp":true}

[
  {
    "success":
    {
      "/config/name":"New Name"
    }
  },
  {
    "success":
    {
      "/config/proxyaddress":" "
    }
  },
  {
    "success":
    {
      "/config/proxyport":0
    }
  },
  {
    "success":
    {
      "/config/dhcp":true
    }
  }
]

CHANGE NAME OF A BULB

PUT /api/0123456789abdcef0123456789abcdef/lights/0 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 17
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"name":"Dining"}

[
  {
    "success":
    {
      "/lights/1/name":"Dining"
    }
  }
]

CHANGE STATE OF A BULB

You can specify which bulb state to change by changing the number in the URL.

For example /api/0123456789abdcef0123456789abcdef/lights/1/state for bulb #1.

PUT /api/0123456789abdcef0123456789abcdef/lights/0/state HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 44
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"bri":230,"xy":[0.63531,0.34127],"on":true}

[
  {
    "success":
    {
      "/lights/0/state/on":true
    }
  },
  {
    "success":
    {
      "/lights/0/state/xy":[0.6353,0.3413]
    }
  },
  {
    "success":
    {
      "/lights/0/state/bri":230
    }
  }
]

CHANGE STATE OF A BULB (BY GROUP)

This request turns off all bulbs in group 0. By default all bulbs are in group 0.

PUT /api/0123456789abdcef0123456789abcdef/groups/0/action HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 12
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"on":false}

[
  {
    "success":
    {
      "/groups/0/action/on":false
    }
  }
]

ADD A NEW SCHEDULE

Schedules are used to turn bulbs on and off at a pre-determined time. You must add a separate schedule for each bulb and each bulb event.

For example, if you have two bulbs and want to turn them on in the morning and off in the evening, you will create four schedules, two schedules to turn the bulbs on and two schedules to turn them off.

You may be able to use schedules with groups but I have not tested that yet.

POST /api/0123456789abdcef0123456789abcdef/schedules HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 240
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{
  "name":"Timer on 807548               ",
  "time":"2012-11-30T18:57:02",
  "description":" ",
  "command":
  {
    "method":"PUT",
    "address":"/api/0123456789abdcef0123456789abcdef/lights/1/state",
    "body":
    {
      "bri":144,
      "ct":469,
      "transitiontime":1800,
      "on":true
    }
  }
}

DELETE A SCHEDULE

DELETE /api/0123456789abdcef0123456789abcdef/schedules/1 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 0
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

[
  {
    "success":"/schedules/1 deleted"
  }
]

SCAN FOR NEW BULBS

This initiates two distinct requests: first an empty POST request to start the search and subsequent GET requests to get search progress.

POST /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 0
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

[
  {
    "success":
    {
      "/lights":"Searching for new devices"
    }
  }
]
GET /api/0123456789abdcef0123456789abcdef/lights/new HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*

{
  "lastscan": "active"
}

ENABLE ALERT MODE FOR A BULB

This makes a light repeatedly turn on and off.

PUT /api/0123456789abdcef0123456789abcdef/lights/0/state HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 19
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0

{"alert":"lselect"}

[
  {
    "success":
    {
      "/lights/0/state/alert":"lselect"
    }
  }
]

EXAMPLE RUBY SCRIPT TO GENERATE A NEW USERNAME

require 'rubygems'
require 'mechanize'
require 'json'

basestation = 'http://10.255.255.44'
username    = '0123456789abdcef0123456789abcdef'

a = Mechanize.new { |agent|
  agent.user_agent = 'hue/1.0.1 CFNetwork/609 Darwin/13.0.0'
}

puts "GET ..."
a.get("#{basestation}/api/#{username}/lights") do |page|
  puts page.body
end

success = false
while success == false
  puts "POST ..."
  page = a.post("#{basestation}/api", {
    "username"   => username,
    "devicetype" => 'iPhone 5',
  }.to_json)

  puts page.body
  json = JSON.parse(page.body)

  if not json[0]["error"]
    success = true
  end

  sleep 1
end