diff --git a/src/join.py b/src/join.py
index 497d642ce951c33e4e1bc1c0d8018e3a7256433c..4909ec267d06e6739fd61d9ee187cf9f7aec922a 100644
--- a/src/join.py
+++ b/src/join.py
@@ -7,22 +7,22 @@ import json
 import logging
 import pandas as pd
 import datetime as dt
+from typing import Iterator, Union, List
 
 join_url_base = 'https://join.fz-juelich.de/services/rest/surfacedata/'
 logging.basicConfig(level=logging.INFO)
 
-def download_join(station_name, statvar):
 
-    """
-    Diese Funktion liest/downloaded daten von JOIN/TOAR
-    Input:
-        param: station_name,    string: Station name e.g. DEBY122
-        param: statvar     ,    dict:   key as variable like 'O3', values as statistics on keys like 'mean'
-
-    Output:
-    # df: pandas df incl. variables & statistics
+def download_join(station_name: Union[str, List[str]], statvar: dict) -> [pd.DataFrame, pd.DataFrame]:
 
     """
+    read data from JOIN/TOAR
+    :param station_name: Station name e.g. DEBY122
+    :param statvar: key as variable like 'O3', values as statistics on keys like 'mean'
+    :returns:
+        - df - pandas df with all variables and statistics
+        - meta - pandas df with all meta information
+    """
     # make sure station_name parameter is a list
     if not isinstance(station_name, list):
         station_name = [station_name]
@@ -69,18 +69,35 @@ def download_join(station_name, statvar):
         raise ValueError("No data found in JOIN.")
 
 
-def _correct_stat_name(stat):
+def _correct_stat_name(stat: str) -> str:
+    """
+    Map given statistic name to new namespace defined by mapping dict. Return given name stat if not element of mapping
+    namespace.
+    :param stat: namespace from JOIN server
+    :return: stat mapped to local namespace
+    """
     mapping = {'average_values': 'mean', 'maximum': 'max', 'minimum': 'min'}
     return mapping.get(stat, stat)
 
 
-def _lower_list(args):
+def _lower_list(args: List[str]) -> Iterator[str]:
+    """
+    lower all elements of given list
+    :param args: list with string entries to lower
+    :return: iterator that lowers all list entries
+    """
     for string in args:
         yield string.lower()
 
 
-def create_url(base, service, **kwargs):
-
+def create_url(base: str, service: str, **kwargs: Union[str, int, float]) -> str:
+    """
+    create a request url with given base url, service type and arbitrarily many additional keyword arguments
+    :param base: basic url of the rest service
+    :param service: service type, e.g. series, stats
+    :param kwargs: keyword pairs for optional request specifications, e.g. 'statistics=maximum'
+    :return: combined url as string
+    """
     url = '{}{}/?'.format(base, service) + '&'.join('{}={}'.format(k, v) for k, v in kwargs.items())
     return url