diff --git a/alta/__init__.py b/alta/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee19b2c4fb3933a3d82460df7fba77a7e39a322b
--- /dev/null
+++ b/alta/__init__.py
@@ -0,0 +1 @@
+from .alta_connector import alta_connector
diff --git a/alta/alta_connector.py b/alta/alta_connector.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e69d064102afca4a7de8dbbfbf0c4fdd7fa311e
--- /dev/null
+++ b/alta/alta_connector.py
@@ -0,0 +1,75 @@
+import requests
+import json
+import io
+import getpass
+import pandas as pd
+
+from typing import Union, Optional
+
+class alta_connector:
+
+    name = "alta"
+
+    def basket_item_to_pandas(
+            self, basket_item: Union[dict, pd.Series], validate: bool = True
+    ) -> Optional[pd.Series]:
+        """Convert an item from the shopping basket into a `pd.Series` with
+        optional validation.
+
+        Parameters
+        ----------
+        basket_item : Union[dict, pd.Series]
+            A single item from a retrieved shopping basket - either a raw `dict`
+            or a converted `pd.Series`.
+        validate : bool
+            If `True`, check that the data in the shopping item conforms with
+            the expected format before attempting the conversion.
+
+        Returns
+        -------
+        Optional[pd.Series]
+            `pd.Series` containing the data encoded in the shopping item or
+            `NoneType`.
+
+        """
+        if validate:
+            item_data = self.validate_basket_item(basket_item, return_loaded=True)
+        else:
+            item_data = json.loads(basket_item["item_data"])
+        if item_data:
+            return pd.Series(item_data)
+        return None
+
+
+    def validate_basket_item(
+            self, basket_item: Union[dict, pd.Series], return_loaded: bool = False
+    ) -> Union[dict, bool, None]:
+        """Check that the data in the shopping item conforms with
+        the expected format
+
+        Parameters
+        ----------
+        basket_item : Union[dict, pd.Series]
+            A single item from a retrieved shopping basket - either a raw `dict`
+            or a converted `pd.Series`.
+        return_loaded : bool
+            If `True`, and validation succeeds return the extracted shopping item
+            as `dict`, otherwise return `True` if validation succeeds and `None`
+            otherwise.
+
+        Returns
+        -------
+        Union[dict, bool, None]
+            If `return_loaded` is `True`, return a `dict` containing the data
+            encoded in the shopping item when validation succeeds.
+            Otherwise if `return_loaded` is `True` validation succeeds.
+            If validation fails return `None`.
+
+        """
+        item_data = json.loads(basket_item["item_data"])
+        if "archive" in item_data and item_data["archive"] == "apertif":
+            if return_loaded:
+                return item_data
+            else:
+                return True
+        return None
\ No newline at end of file
diff --git a/alta/alta_example.py b/alta/alta_example.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3d18c5ae4806abb17e933cbffcd6f88f4ef6449
--- /dev/null
+++ b/alta/alta_example.py
@@ -0,0 +1,28 @@
+from shopping_client import shopping_client
+from alta import alta_connector
+
+esap_api_host = "http://localhost:5555/"
+access_token = "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYzQ5YjQ2OS1kN2FkLTRlNTktYTUwMy1jYWRiYWU5YmQzMGEiLCJuYmYiOjE2MjYxNjc3NDEsInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJpc3MiOiJodHRwczpcL1wvaWFtLWVzY2FwZS5jbG91ZC5jbmFmLmluZm4uaXRcLyIsImV4cCI6MTYyNjE3MTM0MSwiaWF0IjoxNjI2MTY3NzQxLCJqdGkiOiJiMjFlNWE2MC00ZGQ3LTQxNjQtODk3ZS1jMDI0OTEwYjBkZmEiLCJjbGllbnRfaWQiOiI2NjlkN2JlZi0zMmMwLTQ5ODAtYWUzNS1kOGVkZTU2YmQ1ZWYifQ.UNbZkINze8ZgU5MtfAdUQxn7CmTzHrjEGNxYeFsEhtMQSxBCAid6anlOaCppvuegRGTqNAB0XUTOAedtTyWh3X9c-M3jWUTcjAzaeIehYRnv1d0NzjCcQay5UcQ0G5QQ3bDIWqk-iiY-SGDsb-ODiykkrTo-pNoLLtCAiO9ClhQ"
+client = shopping_client(host=esap_api_host,token=access_token)
+
+# read the basket as is, providing a token
+try:
+    basket = client.get_basket()
+    print(basket)
+except:
+    print('no basket found')
+
+# use the alta connector
+
+# Instantiate alta connector
+ac = alta_connector()
+
+# Instantiate ESAP User Profile shopping client, passing alta connector
+sc = shopping_client(host=esap_api_host, token=access_token, connectors=[ac])
+
+# Retrieve basket (prompts to enter access token obtained from ESAP GUI)
+basket=sc.get_basket(convert_to_pandas=False)
+
+print(basket)
+for item in basket:
+    print(item)
\ No newline at end of file
diff --git a/astron_example.py b/astron_example.py
deleted file mode 100644
index 1e82943d641b420023e1c7019e356124c45d053c..0000000000000000000000000000000000000000
--- a/astron_example.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from shopping_client import shopping_client
-
-# for now still onboard this package, probably splitting it off later
-# this is very raw.
-# Officially it doesn't work because a AAI token is required,
-# but in 'development mode' that part is skipped in the backend, so that the results are returned anyway
-# A proper client should log in with AAI though.
-
-token = "eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYzQ5YjQ2OS1kN2FkLTRlNTktYTUwMy1jYWRiYWU5YmQzMGEiLCJuYmYiOjE2MjU0OTM4OTksInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJpc3MiOiJodHRwczpcL1wvaWFtLWVzY2FwZS5jbG91ZC5jbmFmLmluZm4uaXRcLyIsImV4cCI6MTYyNTQ5NzQ5OSwiaWF0IjoxNjI1NDkzODk5LCJqdGkiOiI4NmYxZDI1OC1mOTgzLTQzZWQtODhiYy03NTE2NjM2NDEyZGQiLCJjbGllbnRfaWQiOiI2NjlkN2JlZi0zMmMwLTQ5ODAtYWUzNS1kOGVkZTU2YmQ1ZWYifQ.gGwkDE5P00F-UdRsWazuU1o2QakaN-Vrc8k5vbijLdSTz-O3mrfNqFhxlkfGSno8bz-zRzV2tA8FLPoD5e3B2eOeGtqzTHwMpeJ-t29YwR09YeP5RibfoKh5yr2bEVTfMpBHYZUpZCsXj0m6PcWBvLbNeOIpypUjkseyRaCSHDk"
-client = shopping_client(host="https://sdc-dev.astron.nl:5555/",token=token)
-
-try:
-    basket = client.get_basket()
-    print(basket)
-except:
-    print('no basket found')
\ No newline at end of file