diff --git a/metobsapi/data_api.py b/metobsapi/data_api.py
index cf43c86ef6be4a392bec174f4720aadedfcc5371..81e1e085daf3c579184ba3e1f176fc7cd8db6ac4 100644
--- a/metobsapi/data_api.py
+++ b/metobsapi/data_api.py
@@ -43,6 +43,8 @@ def handle_date(date):
 
 
 def handle_time_string(date_string):
+    if not date_string:
+        return None
     if date_string[0] == "-":
         times = [float(x) for x in date_string[1:].split(":")]
         diff = timedelta(hours=times[0], minutes=times[1], seconds=times[2])
@@ -291,25 +293,46 @@ RESPONSE_HANDLERS = {
 def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order="columns", epoch=None):
     if fmt not in RESPONSE_HANDLERS:
         return render_template("400.html", format=fmt), 400
+    if not interval:
+        interval = "1m"
+
+    try:
+        begin, end = _convert_begin_and_end(begin, end)
+        _check_query_parameters(order, epoch, symbols, interval)
+        short_symbols, symbols = _parse_symbol_names(site, inst, symbols)
+        influx_symbols = handle_symbols(symbols)
+    except ValueError as e:
+        return handle_error(fmt, str(e))
+
+    result, response_info = _query_time_series_db(begin, end, interval, influx_symbols, epoch)
+    frame = handle_influxdb_result(result, influx_symbols, interval)
+    frame = _reorder_and_rename_result_dataframe(frame, symbols, short_symbols)
+    handler = RESPONSE_HANDLERS[fmt]
+    return handler(frame, epoch, sep=sep, order=order, **response_info)
+
 
+def _convert_begin_and_end(begin, end) -> tuple[datetime | timedelta, datetime | timedelta]:
     try:
         # these will be either datetime or timedelta objects
-        begin = handle_time_string(begin) if begin else None
-        end = handle_time_string(end) if end else None
+        begin = handle_time_string(begin)
+        end = handle_time_string(end)
     except (TypeError, ValueError):
-        return handle_error(fmt, "malformed_timestamp")
+        raise ValueError("malformed_timestamp")
+    return begin, end
+
 
+def _check_query_parameters(order, epoch, symbols, interval):
     if order not in ("column", "row"):
-        return handle_error(fmt, "bad_order")
+        raise ValueError("bad_order")
     if epoch and epoch not in data_responses.epoch_translation:
-        return handle_error(fmt, "bad_epoch")
+        raise ValueError("bad_epoch")
     if not symbols:
-        return handle_error(fmt, "missing_symbols")
-    if not interval:
-        interval = "1m"
-    elif interval not in data_responses.INTERVALS:
-        return handle_error(fmt, "bad_interval")
+        raise ValueError("missing_symbols")
+    if interval not in data_responses.INTERVALS:
+        raise ValueError("bad_interval")
+
 
+def _parse_symbol_names(site, inst, symbols):
     if site and inst:
         # shorthand for symbols that all use the same site and inst
         short_symbols = symbols.split(":")
@@ -319,13 +342,11 @@ def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order="
         short_symbols = None
         symbols = symbols.split(":")
     else:
-        return handle_error(fmt, "missing_site_inst")
+        raise ValueError("missing_site_inst")
+    return short_symbols, symbols
 
-    try:
-        influx_symbols = handle_symbols(symbols)
-    except ValueError as e:
-        return handle_error(fmt, str(e))
 
+def _query_time_series_db(begin, end, interval, influx_symbols, epoch):
     if calc_num_records(begin, end, interval) > data_responses.RESPONSES_LIMIT:
         message = "Request will return too many values, please use files API"
         code = 413
@@ -337,13 +358,18 @@ def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order="
         status = "success"
         queries = build_queries(influx_symbols, begin, end, interval)
         result = query(queries, epoch)
+    response_info = {"message": message, "code": code, "status": status}
+    return result, response_info
 
-    frame = handle_influxdb_result(result, influx_symbols, interval)
+
+def _reorder_and_rename_result_dataframe(
+    frame: pd.DataFrame,
+    ordered_symbols: list[str],
+    new_symbol_names: list[str],
+) -> pd.DataFrame:
     # order the resulting symbols the way the user requested
     # assume time is the first column
-    frame = frame[symbols]
-    if site:
-        frame.columns = short_symbols
-
-    handler = RESPONSE_HANDLERS[fmt]
-    return handler(frame, epoch, sep=sep, order=order, status=status, code=code, message=message)
+    frame = frame[ordered_symbols]
+    if new_symbol_names is not None:
+        frame.columns = new_symbol_names
+    return frame