Adam Green
Twitter API Consultant

Twitter API Tools: Get lists owned by a Twitter account

by Adam Green on February 17, 2014

in 140dev Source Code,Twitter API Tools

Installation note: All of the Twitter API tools are built around a set of common library files that must be downloaded and installed before running the code shown here. To run the scripts shown here, just copy them into the same directory as the common files. You can then run it as a web URL, from the command line of a Telnet or SSH client, or as a cron job.

The last API tool showed you how to collect all the members of any Twitter list. Today we will look at another useful technique for lists: collecting details on the lists owned by any account. This is done with the /lists/ownerships API call.

The list data collected by this tool will be stored in a database table called list_ownerships, so it can be used as input for other tools. The MySQL creation statement for this table is at the start of the script. You can copy this statement and paste it into the SQL box in phpMyAdmin.

Before looking at the code, here is some background. Every list on Twitter has a unique list id value, which should be stored as a 64-bit unsigned number. In MySQL terms, this is an unsigned Bigint data type. The other identifier for each list is the slug, which is the list name with spaces replaced by dashes. The combination of the list owner’s screen name and the slug is used to create the URL for the list. This script will also record the full list name with spaces included.

Lists can be either public or private, and this value is returned by the API in an element called mode. When requesting /lists/ownerships, you are given only the account’s public lists, unless the account whose OAuth tokens are being used is the list’s owner. Remember to preserve the privacy of all users. If you do collect data on a private list, you should never display it or share it with anyone.


// Copy lists owned by a user to a database table
// Copyright (c) 2014 Adam Green. All rights reserved. 
// Contact info:, @140dev,
// Released as open source under MIT license

/* Create this table to store lists
CREATE TABLE IF NOT EXISTS `list_ownerships` (
  `list_id` bigint(20) NOT NULL,
  `owner_screen_name` varchar(20) NOT NULL,
  `slug` varchar(100) NOT NULL,
  `name` varchar(100) NOT NULL,
  `created_at` datetime NOT NULL,
  `description` varchar(100) DEFAULT NULL,
  `mode` enum('public','private') NOT NULL,
  `members` int(11) NOT NULL,
  `subscribers` bigint(20) NOT NULL,
  PRIMARY KEY (`list_id`),
  KEY `owner_screen_name` (`owner_screen_name`),
  KEY `slug` (`slug`)

// $owner_screen_name is a string with list owner's screen name
// $table_name is a string with name of DB table for users
// $clear_table is 1 to empty table first, 0 to leave intact
function list_ownerships($owner_screen_name, $table_name, $clear_table=0) {
  if (empty($owner_screen_name) || empty($table_name)) {
    print "ERROR: Invalid arguments";
  // Connect to the database
  $oDB = new db;
  if ($clear_table) {
    // Clear the table of old entries for this owner
    $oDB->select("DELETE FROM $table_name
        WHERE owner_screen_name = '" . $oDB->escape($owner_screen_name) . "'");

  // Connect to API with OAuth
  $connection = get_connection(); 
  // Loop through pages of lists, each page has 20-1000 members
  // This is rate limited to 15 calls per 15 minute window
  // Start cursor at -1, end when cursor becomes 0
  $cursor = -1; 
  while ($cursor<>0) { 
    $connection->request('GET', $connection->url('1.1/lists/ownerships'), 
      array('screen_name' => $owner_screen_name,
        'count' => 100,  // Asking for too many lists can cause a timeout
        'cursor' => $cursor));
    // Exit on API error
    if ($connection->response['code'] <> 200) {
      print "ERROR: " . $connection->response['code'] . "\n";
      print $connection->response['response'];
    $results = json_decode($connection->response['response']);
    $lists = $results->lists;
    foreach($lists as $list) {
      $list_id = $list->id_str;
      // Prevent duplicates
      if (!$oDB->in_table($table_name,"list_id=$list_id")) {
         // Escape string values that may contain quotes
         $field_values = "list_id = $list_id, " .
          "owner_screen_name = '" . $oDB->escape($owner_screen_name) . "', " .
          "slug = '" . $oDB->escape($list->slug) . "', " .
          "name = '" . $oDB->escape($list->name) . "', " .
          "description = '" . $oDB->escape($list->description) . "', " .
          "created_at = '" . $oDB->date($list->created_at) . "', " .
          "members = " . $list->member_count . ", " .
          "subscribers = " . $list->subscriber_count . ", " .
          "mode = '" . $list->mode . "'";
        $oDB->insert($table_name, $field_values);

    // Get the cursor for the next page of results
    $cursor = $results->next_cursor;


You can test this tool with list_ownerships_test.php, which is set to collect all the lists owned by the @twitter account.





Leave a Comment

Previous post:

Next post: