diff --git a/src/execo_g5k/api_cache.py b/src/execo_g5k/api_cache.py
new file mode 100644
index 0000000000000000000000000000000000000000..57f62c2856bfee7698654d2f6d58493745f9fcee
--- /dev/null
+++ b/src/execo_g5k/api_cache.py
@@ -0,0 +1,129 @@
+# Copyright 2009-2014 INRIA Rhone-Alpes, Service Experimentation et
+# Developpement
+#
+# This file is part of Execo.
+#
+# Execo is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Execo is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Execo.  If not, see <http://www.gnu.org/licenses/>
+
+"""Module that manage the cache of the Grid'5000 Reference API (hosts
+and network equipments)
+Data are stored in $HOME/.topo5k under pickle format
+- one file for all hosts
+- one file for all network equipments
+"""
+from os import mkdir, environ
+from pickle import load, dump
+from execo import logger
+from api_utils import get_resource_attributes, get_g5k_sites, get_site_clusters
+
+_cache_dir = environ['HOME'] + '/.g5k/api_cache/'
+
+
+def get_api_data(cache_dir=_cache_dir):
+    """Return two dicts containing the data from network,
+    and hosts """
+    if _is_cache_old(cache_dir):
+        network, hosts = _write_api_cache(cache_dir)
+    else:
+        network, hosts = _read_api_cache(cache_dir)
+
+    return network, hosts
+
+
+def _get_api_commit():
+    """Retrieve the latest api commit"""
+    return get_resource_attributes('')['version']
+
+
+def _is_cache_old(cache_dir=_cache_dir):
+    """Try to read the api_commit stored in the cache_dir and compare
+    it with latest commit, return True if remote commit is different
+    from cache commit"""
+    cache_is_old = False
+    try:
+        f = open(cache_dir + 'api_commit')
+        local_commit = f.readline()
+        f.close()
+        if local_commit != _get_api_commit():
+            logger.debug('Cache is too old')
+            cache_is_old = True
+        else:
+            logger.debug('Already at the latest commit')
+    except:
+        pass
+        logger.debug('No commit version found')
+        cache_is_old = True
+
+    return cache_is_old
+
+
+def _write_api_cache(cache_dir=_cache_dir):
+    """Retrieve data from the Grid'5000 API and write it into
+    the cache directory"""
+    try:
+        mkdir(cache_dir)
+        logger.debug('No cache found, directory created.')
+    except:
+        logger.debug('Cache directory is present')
+        pass
+
+    network, hosts = {}, {}
+    logger.debug('Retrieving topology data from API...')
+    network['backbone'] = get_resource_attributes('/network_equipments')['items']
+
+    for site in sorted(get_g5k_sites()):
+        logger.info(site)
+        hosts[site] = {}
+        for cluster in get_site_clusters(site):
+            logger.info('* ' + cluster)
+            hosts[site][cluster] = get_resource_attributes(
+                'sites/' + site + '/clusters/' + cluster + '/nodes')['items']
+
+        network[site] = get_resource_attributes(
+                    'sites/' + site + '/network_equipments')['items']
+        f = open(cache_dir + site + '_equips', 'w')
+        dump(network[site], f)
+        f.close()
+
+    logger.debug('Writing data to cache ...')
+    f = open(cache_dir + 'network', 'w')
+    dump(network, f)
+    f.close()
+
+    f = open(cache_dir + 'hosts', 'w')
+    dump(hosts, f)
+    f.close()
+
+    f = open(cache_dir + 'api_commit', 'w')
+    f.write(_get_api_commit())
+    f.close()
+
+    return network, hosts
+
+
+def _read_api_cache(cache_dir=_cache_dir):
+    """Read the picke files from cache_dir and return two dicts
+    - network = the network_equipements of all sites and backbone
+    - hosts = the hosts of all sites
+    """
+    logger.debug('Reading data from cache ...')
+    f_network = open(cache_dir + 'network')
+    network = load(f_network)
+    f_network.close()
+
+    f_hosts = open(cache_dir + 'hosts')
+    hosts = load(f_hosts)
+    f_hosts.close()
+
+    return network, hosts