diff --git a/production_tests.sh b/production_tests.sh
index f3655a630081d08ea6fb587057458903ffc7d88b..54493abf9737a9ffe1d33e24f46ff0b40be88f67 100755
--- a/production_tests.sh
+++ b/production_tests.sh
@@ -1,13 +1,12 @@
 #!/bin/bash
+# for running: uvicorn toardb.toardb:app --reload
 
-# for running: uvicorn variables.variables:app --reload
 curl http://127.0.0.1:8000/variables/?limit=3
 curl http://127.0.0.1:8000/variables/id/2
 curl http://127.0.0.1:8000/variables/id/99
 curl http://127.0.0.1:8000/variables/CO
 curl -X POST -H "Content-Type:application/json" -d '{"name": "sabinene", "longname": "sabinene", "displayname": "Sabinene", "cf_standardname": "mole_fraction_of_sabinene_in_air", "units": "nmol mol-1", "chemical_formula": "C10H16"}' http://127.0.0.1:8000/variables/
 
-# for running: uvicorn contacts.contacts:app --reload
 curl http://127.0.0.1:8000/contacts/organisations/
 curl http://127.0.0.1:8000/contacts/organisations/id/2
 curl http://127.0.0.1:8000/contacts/organisations/id/99
@@ -16,15 +15,14 @@ curl -X POST -H "Content-Type:application/json" -d '{"organisation": {"name": "F
 curl http://127.0.0.1:8000/contacts/persons/
 curl http://127.0.0.1:8000/contacts/persons/id/3
 curl http://127.0.0.1:8000/contacts/persons/id/99
-curl "http://127.0.0.1:8000/contacts/persons/Sabine Schröder"
+curl "http://127.0.0.1:8000/contacts/persons/Ute%20Dauert"
+curl "http://127.0.0.1:8000/contacts/persons/Sabine%20Schr%C3%B6der"
 curl -X POST -H "Content-Type:application/json" -d '{"person": {"name": "Martin Schultz", "email": "m.schultz@fz-juelich.de", "phone": "+49-2461-61-96870", "isprivate": true}}' http://127.0.0.1:8000/contacts/persons/
 
-# for running: uvicorn stationmeta.stationmeta:app --reload
 curl http://127.0.0.1:8000/stationmeta_core/
 curl http://127.0.0.1:8000/stationmeta_core/China11
 curl -X POST -H "Content-Type:application/json" -d '{"stationmeta_core": {"codes":["ttt3","ttt4"],"name":"Test_China","coordinates":{"lat":36.256,"lng":17.106,"alt":1534.0},"country":"China","state":"Shandong Sheng","coordinate_validation_status":0,"coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00","type_of_environment":0,"type_of_area":0,"category":"","timezone":"", "coordinate_validator_id": 1, "additional_metadata":"{}"}}' "http://127.0.0.1:8000/stationmeta_core/"
 
-# for running: uvicorn timeseries.timeseries:app --reload
 curl http://127.0.0.1:8000/timeseries/
 curl http://127.0.0.1:8000/timeseries/2
 curl -X POST -H "Content-Type:application/json" -d '{"timeseries": {"label": "CMA2", "order": 1, "access_rights": 0, "sampling_frequency": 0, "aggregation": 0, "data_start_date": "2003-09-07T15:30:00+02:00", "data_end_date": "2016-12-31T14:30:00+01:00", "measurement_method": "UV absorption", "sampling_height": 7.0, "date_added": "2020-05-15T15:30:00+02:00", "date_modified": "2020-05-16T09:30:00+02:00", "station_id": 2, "variable_id": 7, "additional_metadata":"{}"}}' http://127.0.0.1:8000/timeseries/
diff --git a/auth_user/__init__.py b/toardb/__init__.py
similarity index 100%
rename from auth_user/__init__.py
rename to toardb/__init__.py
diff --git a/auth_user/README.md b/toardb/auth_user/README.md
similarity index 100%
rename from auth_user/README.md
rename to toardb/auth_user/README.md
diff --git a/contacts/__init__.py b/toardb/auth_user/__init__.py
similarity index 100%
rename from contacts/__init__.py
rename to toardb/auth_user/__init__.py
diff --git a/auth_user/auth_user.py b/toardb/auth_user/auth_user.py
similarity index 100%
rename from auth_user/auth_user.py
rename to toardb/auth_user/auth_user.py
diff --git a/auth_user/fixtures/auth.json b/toardb/auth_user/fixtures/auth.json
similarity index 100%
rename from auth_user/fixtures/auth.json
rename to toardb/auth_user/fixtures/auth.json
diff --git a/auth_user/fixtures/authtoken.json b/toardb/auth_user/fixtures/authtoken.json
similarity index 100%
rename from auth_user/fixtures/authtoken.json
rename to toardb/auth_user/fixtures/authtoken.json
diff --git a/auth_user/models.py b/toardb/auth_user/models.py
similarity index 100%
rename from auth_user/models.py
rename to toardb/auth_user/models.py
diff --git a/auth_user/schemas.py b/toardb/auth_user/schemas.py
similarity index 100%
rename from auth_user/schemas.py
rename to toardb/auth_user/schemas.py
diff --git a/data/__init__.py b/toardb/contacts/__init__.py
similarity index 100%
rename from data/__init__.py
rename to toardb/contacts/__init__.py
diff --git a/contacts/contacts.py b/toardb/contacts/contacts.py
similarity index 77%
rename from contacts/contacts.py
rename to toardb/contacts/contacts.py
index 8b632bd2df8265a531c38aa1f630da31ddfb9469..9f578a8f459c003fd55dfb088fe2b18973fa515c 100644
--- a/contacts/contacts.py
+++ b/toardb/contacts/contacts.py
@@ -3,12 +3,12 @@ Simple API for contacts management
 """
 
 from typing import List
-from fastapi import FastAPI, Depends, HTTPException, Body
+from fastapi import APIRouter, Depends, HTTPException, Body
 from sqlalchemy.orm import Session
 from . import crud, schemas
-from utils.database import ToarDbSession
+from toardb.utils.database import ToarDbSession
 
-app = FastAPI()
+router = APIRouter()
 
 # Dependency
 def get_db():
@@ -22,20 +22,20 @@ def get_db():
 # plain views to post and get contacts
 
 #get all entries of table persons
-@app.get('/contacts/persons/', response_model=List[schemas.Person])
+@router.get('/contacts/persons/', response_model=List[schemas.Person])
 def get_all_persons(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     persons = crud.get_all_persons(db, skip=skip, limit=limit)
     return persons
 
 #get all metadata of one person
-@app.get('/contacts/persons/id/{person_id}', response_model=schemas.Person)
+@router.get('/contacts/persons/id/{person_id}', response_model=schemas.Person)
 def get_person(person_id: int, db: Session = Depends(get_db)):
     db_person = crud.get_person(db, person_id=person_id)
     if db_person is None:
         raise HTTPException(status_code=404, detail="Person not found.")
     return db_person
 
-@app.get('/contacts/persons/{name}', response_model=schemas.Person)
+@router.get('/contacts/persons/{name}', response_model=schemas.Person)
 def get_person(name: str, db: Session = Depends(get_db)):
     db_person = crud.get_person_by_name(db, name=name)
     if db_person is None:
@@ -47,7 +47,7 @@ def get_person(name: str, db: Session = Depends(get_db)):
 #
 #
 
-@app.post('/contacts/persons/', response_model=schemas.Person)
+@router.post('/contacts/persons/', response_model=schemas.Person)
 def create_person(person: schemas.PersonCreate = Body(..., embed = True), db: Session = Depends(get_db)):
     db_person = crud.get_person_by_name(db, name=person.name)
     if db_person:
@@ -58,20 +58,20 @@ def create_person(person: schemas.PersonCreate = Body(..., embed = True), db: Se
 # plain views to post and get organisations
 
 #get all entries of table organisations
-@app.get('/contacts/organisations/', response_model=List[schemas.Organisation])
+@router.get('/contacts/organisations/', response_model=List[schemas.Organisation])
 def get_all_organisations(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     organisations = crud.get_all_organisations(db, skip=skip, limit=limit)
     return organisations
 
 #get all metadata of one organisation
-@app.get('/contacts/organisations/id/{organisation_id}', response_model=schemas.Organisation)
+@router.get('/contacts/organisations/id/{organisation_id}', response_model=schemas.Organisation)
 def get_organisation(organisation_id: int, db: Session = Depends(get_db)):
     db_organisation = crud.get_organisation (db, organisation_id=organisation_id)
     if db_organisation is None:
         raise HTTPException(status_code=404, detail="Organisation not found.")
     return db_organisation
 
-@app.get('/contacts/organisations/{name}', response_model=schemas.Organisation)
+@router.get('/contacts/organisations/{name}', response_model=schemas.Organisation)
 def get_organisation(name: str, db: Session = Depends(get_db)):
     db_organisation = crud.get_organisation_by_name(db, name=name)
     if db_organisation is None:
@@ -84,9 +84,8 @@ def get_organisation(name: str, db: Session = Depends(get_db)):
 #
 #
 
-@app.post('/contacts/organisations/', response_model=schemas.Organisation)
+@router.post('/contacts/organisations/', response_model=schemas.Organisation)
 def create_organisation(organisation: schemas.OrganisationCreate = Body(..., embed = True), db: Session = Depends(get_db)):
-    print("in contacts.py: ", organisation)
     db_organisation = crud.get_organisation_by_name(db, name=organisation.name)
     if db_organisation:
         raise HTTPException(status_code=400, detail="Organisation already registered.")
diff --git a/contacts/crud.py b/toardb/contacts/crud.py
similarity index 100%
rename from contacts/crud.py
rename to toardb/contacts/crud.py
diff --git a/contacts/fixtures/organisations.json b/toardb/contacts/fixtures/organisations.json
similarity index 100%
rename from contacts/fixtures/organisations.json
rename to toardb/contacts/fixtures/organisations.json
diff --git a/contacts/fixtures/persons.json b/toardb/contacts/fixtures/persons.json
similarity index 100%
rename from contacts/fixtures/persons.json
rename to toardb/contacts/fixtures/persons.json
diff --git a/contacts/models.py b/toardb/contacts/models.py
similarity index 100%
rename from contacts/models.py
rename to toardb/contacts/models.py
diff --git a/contacts/models_organisation.py b/toardb/contacts/models_organisation.py
similarity index 100%
rename from contacts/models_organisation.py
rename to toardb/contacts/models_organisation.py
diff --git a/contacts/models_person.py b/toardb/contacts/models_person.py
similarity index 100%
rename from contacts/models_person.py
rename to toardb/contacts/models_person.py
diff --git a/contacts/schemas.py b/toardb/contacts/schemas.py
similarity index 100%
rename from contacts/schemas.py
rename to toardb/contacts/schemas.py
diff --git a/contacts/test_base.py b/toardb/contacts/test_base.py
similarity index 95%
rename from contacts/test_base.py
rename to toardb/contacts/test_base.py
index 377af356f266a003bf5d02345e2e63c4f0456bfa..70113f71186ca3e4a4b90b1a25e40878fcb77e3f 100644
--- a/contacts/test_base.py
+++ b/toardb/contacts/test_base.py
@@ -7,9 +7,10 @@ from sqlalchemy.engine import Engine as Database
 from sqlalchemy.orm import Session
 from sqlalchemy_utils import database_exists, create_database, drop_database
 
-from utils.database import DATABASE_URL
+from toardb.utils.database import DATABASE_URL
 from .models import Base
-from .contacts import app, get_db
+from toardb.toardb import app
+from toardb.contacts.contacts import get_db
 
 url = str(DATABASE_URL+ "_test")
 _db_conn = create_engine(url)
diff --git a/contacts/test_contacts.py b/toardb/contacts/test_contacts.py
similarity index 98%
rename from contacts/test_contacts.py
rename to toardb/contacts/test_contacts.py
index 840b58460991c0dd4222f517b4c8bf0f90a0b468..162883b20e596170a97f5857d66dd9c5e3c35290 100644
--- a/contacts/test_contacts.py
+++ b/toardb/contacts/test_contacts.py
@@ -29,7 +29,7 @@ class TestApps:
         fake_conn.commit()
         fake_cur.execute("ALTER SEQUENCE organisations_id_seq RESTART WITH 1")
         fake_conn.commit()
-        infilename = "contacts/fixtures/persons.json"
+        infilename = "toardb/contacts/fixtures/persons.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -37,7 +37,7 @@ class TestApps:
                 db.add(new_person)
                 db.commit()
                 db.refresh(new_person)
-        infilename = "contacts/fixtures/organisations.json"
+        infilename = "toardb/contacts/fixtures/organisations.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
diff --git a/stationmeta/__init__.py b/toardb/data/__init__.py
similarity index 100%
rename from stationmeta/__init__.py
rename to toardb/data/__init__.py
diff --git a/data/crud.py b/toardb/data/crud.py
similarity index 91%
rename from data/crud.py
rename to toardb/data/crud.py
index b4e4954f11cd7ed09dd314f9b66030c053347e09..8158dcd82acd64e328b678ee35bde951eb2fb89d 100644
--- a/data/crud.py
+++ b/toardb/data/crud.py
@@ -10,14 +10,14 @@ from sqlalchemy.engine import Engine
 from fastapi import File, UploadFile
 from fastapi.responses import JSONResponse
 from . import models, schemas
-from variables import models as variables_models
-from stationmeta import models as stationmeta_models
-from stationmeta.crud import get_stationmeta_core
-from timeseries.crud import get_timeseries_by_unique_constraints
+from toardb.variables import models as variables_models
+from toardb.stationmeta import models as stationmeta_models
+from toardb.stationmeta.crud import get_stationmeta_core
+from toardb.timeseries.crud import get_timeseries_by_unique_constraints
 import datetime as dt
 import pandas as pd
 from io import StringIO
-from utils.database import engine
+from toardb.utils.database import engine
 
 def get_data(db: Session, timeseries_id: int):
     return db.query(models.Data).filter(models.Data.timeseries_id == timeseries_id).all()
diff --git a/data/data.py b/toardb/data/data.py
similarity index 82%
rename from data/data.py
rename to toardb/data/data.py
index 4f972fd6b871a9cc1f9f6995758c1d30dafe4467..c042383c43cdb2b8c315f84f644f4a2872f77fc9 100644
--- a/data/data.py
+++ b/toardb/data/data.py
@@ -3,13 +3,13 @@ Simple test API for data management
 """
 
 from typing import List
-from fastapi import FastAPI, Depends, HTTPException, \
+from fastapi import APIRouter, Depends, HTTPException, \
                     File, UploadFile
 from sqlalchemy.orm import Session
 from . import crud, schemas
-from utils.database import ToarDbSession
+from toardb.utils.database import ToarDbSession
 
-app = FastAPI()
+router = APIRouter()
 
 # Dependency
 def get_db():
@@ -24,13 +24,13 @@ def get_db():
 # plain views to post and get data
 
 #get all data of table data
-@app.get('/data/', response_model=List[schemas.Data])
+@router.get('/data/', response_model=List[schemas.Data])
 def get_all_data(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     data = crud.get_all_data(db, skip=skip, limit=limit)
     return data
 
 #get all data of one timeseries
-@app.get('/data/{timeseries_id}', response_model=List[schemas.Data])
+@router.get('/data/{timeseries_id}', response_model=List[schemas.Data])
 def get_data(timeseries_id: int, db: Session = Depends(get_db)):
     db_data = crud.get_data(db, timeseries_id=timeseries_id)
     if db_data is None:
@@ -42,7 +42,7 @@ def get_data(timeseries_id: int, db: Session = Depends(get_db)):
 # - get all data of one special timestamp and timeseries
 # - ...
 
-@app.post('/data/', response_model=schemas.DataCreate)
+@router.post('/data/', response_model=schemas.DataCreate)
 async def create_data(file: UploadFile = File(...), db: Session = Depends(get_db)):
 #   # the next three lines are automatically done by database management,
 #   # but we do want helpful error messages!
diff --git a/data/models.py b/toardb/data/models.py
similarity index 100%
rename from data/models.py
rename to toardb/data/models.py
diff --git a/data/schemas.py b/toardb/data/schemas.py
similarity index 100%
rename from data/schemas.py
rename to toardb/data/schemas.py
diff --git a/timeseries/__init__.py b/toardb/stationmeta/__init__.py
similarity index 100%
rename from timeseries/__init__.py
rename to toardb/stationmeta/__init__.py
diff --git a/stationmeta/crud.py b/toardb/stationmeta/crud.py
similarity index 100%
rename from stationmeta/crud.py
rename to toardb/stationmeta/crud.py
diff --git a/stationmeta/fixtures/stationmeta_core.json b/toardb/stationmeta/fixtures/stationmeta_core.json
similarity index 100%
rename from stationmeta/fixtures/stationmeta_core.json
rename to toardb/stationmeta/fixtures/stationmeta_core.json
diff --git a/stationmeta/models.py b/toardb/stationmeta/models.py
similarity index 100%
rename from stationmeta/models.py
rename to toardb/stationmeta/models.py
diff --git a/stationmeta/models_annotation.py b/toardb/stationmeta/models_annotation.py
similarity index 98%
rename from stationmeta/models_annotation.py
rename to toardb/stationmeta/models_annotation.py
index 7c78215c3712397a90b4ff699fabcb8182e32cff..40cb5fcbe02590bf74069515773092d5a2fe3235 100644
--- a/stationmeta/models_annotation.py
+++ b/toardb/stationmeta/models_annotation.py
@@ -7,7 +7,7 @@ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, Strin
                        Text, Boolean, CheckConstraint
 #from sqlalchemy.orm import relationship
 from sqlalchemy.ext.declarative import declarative_base
-from auth_user.models import AuthUser
+from toardb.auth_user.models import AuthUser
 from .models_core import StationmetaCore 
 
 Base = declarative_base()
diff --git a/stationmeta/models_aux.py b/toardb/stationmeta/models_aux.py
similarity index 100%
rename from stationmeta/models_aux.py
rename to toardb/stationmeta/models_aux.py
diff --git a/stationmeta/models_core.py b/toardb/stationmeta/models_core.py
similarity index 99%
rename from stationmeta/models_core.py
rename to toardb/stationmeta/models_core.py
index c8059d38cbc03a5c926cb08dde8a5189b7ff4d5f..e27599605b8c335bf2d6160f2c8796e0dbe6f2b9 100644
--- a/stationmeta/models_core.py
+++ b/toardb/stationmeta/models_core.py
@@ -10,7 +10,7 @@ from sqlalchemy.orm import relationship
 from sqlalchemy.dialects.postgresql import JSONB, ARRAY
 from sqlalchemy.ext.declarative import declarative_base
 from shapely import wkt
-from auth_user.models import AuthUser
+from toardb.auth_user.models import AuthUser
 
 Base = declarative_base()
 metadata = Base.metadata
diff --git a/stationmeta/models_global.py b/toardb/stationmeta/models_global.py
similarity index 100%
rename from stationmeta/models_global.py
rename to toardb/stationmeta/models_global.py
diff --git a/stationmeta/models_global_services.py b/toardb/stationmeta/models_global_services.py
similarity index 100%
rename from stationmeta/models_global_services.py
rename to toardb/stationmeta/models_global_services.py
diff --git a/stationmeta/models_role.py b/toardb/stationmeta/models_role.py
similarity index 98%
rename from stationmeta/models_role.py
rename to toardb/stationmeta/models_role.py
index d872d24685423680aff23733647c9d6199b721ad..f7dc21e56ced1ed65930893092d6d76a383a0369 100644
--- a/stationmeta/models_role.py
+++ b/toardb/stationmeta/models_role.py
@@ -7,7 +7,7 @@ from sqlalchemy import Column, ForeignKey, Integer, text, \
                        CheckConstraint, UniqueConstraint
 #from sqlalchemy.orm import relationship
 from sqlalchemy.ext.declarative import declarative_base
-from contacts.models import Person
+from toardb.contacts.models import Person
 from .models_core import StationmetaCore
 
 Base = declarative_base()
diff --git a/stationmeta/pydantic_toar_testing.py b/toardb/stationmeta/pydantic_toar_testing.py
similarity index 100%
rename from stationmeta/pydantic_toar_testing.py
rename to toardb/stationmeta/pydantic_toar_testing.py
diff --git a/stationmeta/schemas.py b/toardb/stationmeta/schemas.py
similarity index 100%
rename from stationmeta/schemas.py
rename to toardb/stationmeta/schemas.py
diff --git a/stationmeta/stationmeta.py b/toardb/stationmeta/stationmeta.py
similarity index 87%
rename from stationmeta/stationmeta.py
rename to toardb/stationmeta/stationmeta.py
index a5ed0e6f33e173354be103dd30955d77d0c9e43f..6367f09d1902bb18937c54b353cff30fcb68a32a 100644
--- a/stationmeta/stationmeta.py
+++ b/toardb/stationmeta/stationmeta.py
@@ -3,13 +3,13 @@ Simple test API for stationmeta management
 """
 
 from typing import List
-from fastapi import FastAPI, Depends, HTTPException, Body
+from fastapi import APIRouter, Depends, HTTPException, Body
 from sqlalchemy.orm import Session, sessionmaker
 from . import crud, schemas
 from sqlalchemy import create_engine
-from utils.database import DATABASE_URL
+from toardb.utils.database import DATABASE_URL
 
-app = FastAPI()
+router = APIRouter()
 
 # Dependency
 #def get_db():
@@ -38,13 +38,13 @@ async def get_db():
 # plain views to post and get stationmeta
 
 #get all entries of table stationmeta
-@app.get('/stationmeta_core/', response_model=List[schemas.StationmetaCore])
+@router.get('/stationmeta_core/', response_model=List[schemas.StationmetaCore])
 def get_all_stationmeta_core(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     stationmeta_core = crud.get_all_stationmeta_core(db, skip=skip, limit=limit)
     return stationmeta_core
 
 #get all core metadata of one station
-@app.get('/stationmeta_core/{station_code}', response_model=schemas.StationmetaCore)
+@router.get('/stationmeta_core/{station_code}', response_model=schemas.StationmetaCore)
 def get_stationmeta_core(station_code: str, db: Session = Depends(get_db)):
     db_stationmeta_core = crud.get_stationmeta_core(db, station_code=station_code)
     if db_stationmeta_core is None:
@@ -56,7 +56,7 @@ def get_stationmeta_core(station_code: str, db: Session = Depends(get_db)):
 # - get stationmeta_aux
 # - ...
 
-@app.post('/stationmeta_core/', response_model=schemas.StationmetaCore)
+@router.post('/stationmeta_core/', response_model=schemas.StationmetaCore)
 #curl -X POST -H "Content-Type:application/json" -d '{"stationmeta_core": {"codes":["ttt3","ttt4"],"name":"Test_China","coordinates":{"lat":36.256,"lng":17.106,"alt":1534.0},"country":"China","state":"Shandong Sheng","coordinate_validation_status":0,"coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00","type_of_environment":0,"type_of_area":0,"category":"","timezone":"", "coordinate_validator_id": 1, "additional_metadata":"{}"}}' "http://127.0.0.1:8000/stationmeta_core/"
 # The following command was not working as long as the upload via Body was defined.
 # See bug report: https://github.com/tiangolo/fastapi/issues/300
diff --git a/stationmeta/test_base.py b/toardb/stationmeta/test_base.py
similarity index 94%
rename from stationmeta/test_base.py
rename to toardb/stationmeta/test_base.py
index 2871a87f285b99ba67a58b817a8096c4487dd742..bd411c787b28c7cf12c811f968238262ceb5a698 100644
--- a/stationmeta/test_base.py
+++ b/toardb/stationmeta/test_base.py
@@ -7,11 +7,12 @@ from sqlalchemy.engine import Engine as Database
 from sqlalchemy.orm import Session
 from sqlalchemy_utils import database_exists, create_database, drop_database
 
-from utils.database import DATABASE_URL
+from toardb.utils.database import DATABASE_URL
 from .models import Base
-from auth_user.models import Base as AuthUserBase
-from contacts.models import Base as ContactBase
-from .stationmeta import app, get_db
+from toardb.auth_user.models import Base as AuthUserBase
+from toardb.contacts.models import Base as ContactBase
+from toardb.toardb import app
+from toardb.stationmeta.stationmeta import get_db
 
 url = str(DATABASE_URL+ "_test")
 _db_conn = create_engine(url)
diff --git a/stationmeta/test_stationmeta.py b/toardb/stationmeta/test_stationmeta.py
similarity index 96%
rename from stationmeta/test_stationmeta.py
rename to toardb/stationmeta/test_stationmeta.py
index 64bec3824ce7d1f6c8fa97f279575f375e9e7aad..b7b9a184fcc1af1801ca5417c014b57bacece194 100644
--- a/stationmeta/test_stationmeta.py
+++ b/toardb/stationmeta/test_stationmeta.py
@@ -1,8 +1,8 @@
 import pytest
 import json
 from .models import StationmetaCore
-from auth_user.models import AuthUser
-from contacts.models import Person, Organisation
+from toardb.auth_user.models import AuthUser
+from toardb.contacts.models import Person, Organisation
 from .schemas import get_geom_from_coordinates, Coordinates
 # Required imports 'create_test_database'
 from .test_base import (
@@ -50,7 +50,7 @@ class TestApps:
         fake_conn.commit()
         fake_cur.execute("ALTER SEQUENCE organisations_id_seq RESTART WITH 1")
         fake_conn.commit()
-        infilename = "auth_user/fixtures/auth.json"
+        infilename = "toardb/auth_user/fixtures/auth.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -58,7 +58,7 @@ class TestApps:
                 db.add(new_auth_user)
                 db.commit()
                 db.refresh(new_auth_user)
-        infilename = "contacts/fixtures/persons.json"
+        infilename = "toardb/contacts/fixtures/persons.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -66,7 +66,7 @@ class TestApps:
                 db.add(new_person)
                 db.commit()
                 db.refresh(new_person)
-        infilename = "contacts/fixtures/organisations.json"
+        infilename = "toardb/contacts/fixtures/organisations.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -74,7 +74,7 @@ class TestApps:
                 db.add(new_organisation)
                 db.commit()
                 db.refresh(new_organisation)
-        infilename = "stationmeta/fixtures/stationmeta_core.json"
+        infilename = "toardb/stationmeta/fixtures/stationmeta_core.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
diff --git a/utils/__init__.py b/toardb/timeseries/__init__.py
similarity index 100%
rename from utils/__init__.py
rename to toardb/timeseries/__init__.py
diff --git a/timeseries/crud.py b/toardb/timeseries/crud.py
similarity index 98%
rename from timeseries/crud.py
rename to toardb/timeseries/crud.py
index 9b2eaa791efda90aac076ebca7fb704aec710c8b..7abde3481ef1108e29f592650953c15dcc1d93e2 100644
--- a/timeseries/crud.py
+++ b/toardb/timeseries/crud.py
@@ -43,7 +43,6 @@ def create_timeseries(db: Session, timeseries: TimeseriesCreate):
     # in upload command, we have now: "additional_metadata": "{}"
     # but return from this method gives: "additional_metadata": {}
     # ==> there is a mismatch between model(JSONB) and schema(JSON)
-    print("in crud: ",db_timeseries)
     db_timeseries.additional_metadata = str(db_timeseries.additional_metadata)
     db.add(db_timeseries)
     result = db.commit()
diff --git a/timeseries/fixtures/timeseries.json b/toardb/timeseries/fixtures/timeseries.json
similarity index 100%
rename from timeseries/fixtures/timeseries.json
rename to toardb/timeseries/fixtures/timeseries.json
diff --git a/timeseries/models.py b/toardb/timeseries/models.py
similarity index 100%
rename from timeseries/models.py
rename to toardb/timeseries/models.py
diff --git a/timeseries/models_annotation.py b/toardb/timeseries/models_annotation.py
similarity index 98%
rename from timeseries/models_annotation.py
rename to toardb/timeseries/models_annotation.py
index 2e61ab78a0144ef95d226231d2fa3c4bd41adda0..058c9e60e7bfad9d18aabc118383e30a3a974598 100644
--- a/timeseries/models_annotation.py
+++ b/toardb/timeseries/models_annotation.py
@@ -7,7 +7,7 @@ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, Strin
                        Text, Boolean, CheckConstraint
 #from sqlalchemy.orm import relationship
 from sqlalchemy.ext.declarative import declarative_base
-from auth_user.models import AuthUser
+from toardb.auth_user.models import AuthUser
 from .models_core import Timeseries
 
 Base = declarative_base()
diff --git a/timeseries/models_core.py b/toardb/timeseries/models_core.py
similarity index 98%
rename from timeseries/models_core.py
rename to toardb/timeseries/models_core.py
index 1298ad7e976b44ff1e5a8a0bcb260af4ff15c6ae..f71300956c45f6f6b5ea7e199871637157c4aaee 100644
--- a/timeseries/models_core.py
+++ b/toardb/timeseries/models_core.py
@@ -4,8 +4,8 @@ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, Strin
 #from sqlalchemy.orm import relationship
 from sqlalchemy.dialects.postgresql import JSONB
 from sqlalchemy.ext.declarative import declarative_base
-from stationmeta.models import StationmetaCore
-from variables.models import Variable
+from toardb.stationmeta.models import StationmetaCore
+from toardb.variables.models import Variable
 
 Base = declarative_base()
 metadata = Base.metadata
diff --git a/timeseries/models_programme.py b/toardb/timeseries/models_programme.py
similarity index 100%
rename from timeseries/models_programme.py
rename to toardb/timeseries/models_programme.py
diff --git a/timeseries/models_role.py b/toardb/timeseries/models_role.py
similarity index 98%
rename from timeseries/models_role.py
rename to toardb/timeseries/models_role.py
index 9e3191ec7e957da3d62bc035f6eec87ae77fb5f0..65c2327fa280482359b76b2ecb03062daad468f5 100644
--- a/timeseries/models_role.py
+++ b/toardb/timeseries/models_role.py
@@ -7,7 +7,7 @@ from sqlalchemy import Column, ForeignKey, Integer, text, \
                        CheckConstraint, UniqueConstraint
 #from sqlalchemy.orm import relationship
 from sqlalchemy.ext.declarative import declarative_base
-from contacts.models import Person
+from toardb.contacts.models import Person
 from .models_core import Timeseries
 
 Base = declarative_base()
diff --git a/timeseries/pydantic_toar_testing.py b/toardb/timeseries/pydantic_toar_testing.py
similarity index 100%
rename from timeseries/pydantic_toar_testing.py
rename to toardb/timeseries/pydantic_toar_testing.py
diff --git a/timeseries/schemas.py b/toardb/timeseries/schemas.py
similarity index 100%
rename from timeseries/schemas.py
rename to toardb/timeseries/schemas.py
diff --git a/timeseries/test_base.py b/toardb/timeseries/test_base.py
similarity index 94%
rename from timeseries/test_base.py
rename to toardb/timeseries/test_base.py
index 8a76e31f67d63b8c03cece639daf5af4f6b17587..259b2b38f75a136f098aaf839e63e3796fad3631 100644
--- a/timeseries/test_base.py
+++ b/toardb/timeseries/test_base.py
@@ -7,13 +7,14 @@ from sqlalchemy.engine import Engine as Database
 from sqlalchemy.orm import Session
 from sqlalchemy_utils import database_exists, create_database, drop_database
 
-from utils.database import DATABASE_URL
+from toardb.utils.database import DATABASE_URL
 from .models import Base
-from variables.models import Base as VariableBase
-from stationmeta.models import Base as StationmetaBase
-from auth_user.models import Base as AuthUserBase
-from contacts.models import Base as ContactBase
-from .timeseries import app, get_db
+from toardb.variables.models import Base as VariableBase
+from toardb.stationmeta.models import Base as StationmetaBase
+from toardb.auth_user.models import Base as AuthUserBase
+from toardb.contacts.models import Base as ContactBase
+from toardb.toardb import app
+from toardb.timeseries.timeseries import get_db
  
 url = str(DATABASE_URL+ "_test")
 _db_conn = create_engine(url)
diff --git a/timeseries/test_timeseries.py b/toardb/timeseries/test_timeseries.py
similarity index 93%
rename from timeseries/test_timeseries.py
rename to toardb/timeseries/test_timeseries.py
index f15df0a6c291da92f3c8e481237259c35d025bb7..0c1dd03595c40dc8307f81a0923c476dbd351254 100644
--- a/timeseries/test_timeseries.py
+++ b/toardb/timeseries/test_timeseries.py
@@ -1,11 +1,11 @@
 import pytest
 import json
 from .models import Timeseries
-from stationmeta.models import StationmetaCore
-from stationmeta.schemas import get_geom_from_coordinates, Coordinates
-from variables.models import Variable
-from contacts.models import Person, Organisation
-from auth_user.models import AuthUser
+from toardb.stationmeta.models import StationmetaCore
+from toardb.stationmeta.schemas import get_geom_from_coordinates, Coordinates
+from toardb.variables.models import Variable
+from toardb.contacts.models import Person, Organisation
+from toardb.auth_user.models import AuthUser
 # Required imports 'create_test_database'
 from .test_base import (
     client,
@@ -60,7 +60,7 @@ class TestApps:
         fake_conn.commit()
         fake_cur.execute("ALTER SEQUENCE timeseries_id_seq RESTART WITH 1")
         fake_conn.commit()
-        infilename = "auth_user/fixtures/auth.json"
+        infilename = "toardb/auth_user/fixtures/auth.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -68,7 +68,7 @@ class TestApps:
                 db.add(new_auth_user)
                 db.commit()
                 db.refresh(new_auth_user)
-        infilename = "contacts/fixtures/persons.json"
+        infilename = "toardb/contacts/fixtures/persons.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -76,7 +76,7 @@ class TestApps:
                 db.add(new_person)
                 db.commit()
                 db.refresh(new_person)
-        infilename = "contacts/fixtures/organisations.json"
+        infilename = "toardb/contacts/fixtures/organisations.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -84,7 +84,7 @@ class TestApps:
                 db.add(new_organisation)
                 db.commit()
                 db.refresh(new_organisation)
-        infilename = "variables/fixtures/variables.json"
+        infilename = "toardb/variables/fixtures/variables.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -92,7 +92,7 @@ class TestApps:
                 db.add(new_variable)
                 db.commit()
                 db.refresh(new_variable)
-        infilename = "stationmeta/fixtures/stationmeta_core.json"
+        infilename = "toardb/stationmeta/fixtures/stationmeta_core.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
@@ -108,7 +108,7 @@ class TestApps:
                 db.add(new_stationmeta_core)
                 db.commit()
                 db.refresh(new_stationmeta_core)
-        infilename = "timeseries/fixtures/timeseries.json"
+        infilename = "toardb/timeseries/fixtures/timeseries.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
diff --git a/timeseries/timeseries.py b/toardb/timeseries/timeseries.py
similarity index 69%
rename from timeseries/timeseries.py
rename to toardb/timeseries/timeseries.py
index 9ce91d9c1151c4e90e973cf77de108dddb612161..8c0fa82db69367c7fd4cd96b86545eb82f0ed1ba 100644
--- a/timeseries/timeseries.py
+++ b/toardb/timeseries/timeseries.py
@@ -3,12 +3,12 @@ Simple test API for timeseries management
 """
 
 from typing import List
-from fastapi import FastAPI, Depends, HTTPException, Body
+from fastapi import APIRouter, Depends, HTTPException, Body
 from sqlalchemy.orm import Session
 from . import crud, schemas
-from utils.database import ToarDbSession
+from toardb.utils.database import ToarDbSession
 
-app = FastAPI()
+router = APIRouter()
 
 # Dependency
 def get_db():
@@ -23,13 +23,13 @@ def get_db():
 # plain views to post and get timeseries
 
 #get all entries of table timeseries
-@app.get('/timeseries/', response_model=List[schemas.Timeseries])
+@router.get('/timeseries/', response_model=List[schemas.Timeseries])
 def get_all_timeseries(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     timeseries = crud.get_all_timeseries(db, skip=skip, limit=limit)
     return timeseries
 
 #get all metadata of one timeseries
-@app.get('/timeseries/{timeseries_id}', response_model=schemas.Timeseries)
+@router.get('/timeseries/{timeseries_id}', response_model=schemas.Timeseries)
 def get_timeseries(timeseries_id: int, db: Session = Depends(get_db)):
     db_timeseries = crud.get_timeseries(db, timeseries_id=timeseries_id)
     if db_timeseries is None:
@@ -42,9 +42,10 @@ def get_timeseries(timeseries_id: int, db: Session = Depends(get_db)):
 #
 
 # still to be tested:
-@app.post('/timeseries/', response_model=schemas.Timeseries)
+@router.post('/timeseries/', response_model=schemas.Timeseries)
 def create_timeseries(timeseries: schemas.TimeseriesCreate = Body(..., embed = True), db: Session = Depends(get_db)):
-    db_timeseries = crud.get_timeseries(db, timeseries_id=timeseries.id)
+    db_timeseries = crud.get_timeseries_by_unique_constraints(db, station_id=timeseries.station_id,
+                         variable_id=timeseries.variable_id, label=timeseries.label)
     if db_timeseries:
         raise HTTPException(status_code=400, detail="Timeseries already registered.")
     return crud.create_timeseries(db=db, timeseries=timeseries)
diff --git a/toardb/toardb.py b/toardb/toardb.py
new file mode 100644
index 0000000000000000000000000000000000000000..95d30c78b2d749f6ee1dc7a63cf3ee4f1800d7be
--- /dev/null
+++ b/toardb/toardb.py
@@ -0,0 +1,33 @@
+"""
+Simple test API for variable management
+"""
+
+from typing import List
+from fastapi import FastAPI, Depends, HTTPException, APIRouter
+from sqlalchemy.orm import Session
+
+from toardb.utils.database import ToarDbSession
+
+from toardb.variables import variables
+from toardb.contacts import contacts
+from toardb.stationmeta import stationmeta
+from toardb.timeseries import timeseries
+from toardb.data import data
+
+
+app = FastAPI()
+
+# Dependency
+def get_db():
+    try:
+        db = ToarDbSession()
+        yield db
+    finally:
+        db.close()
+
+app.include_router(variables.router)
+app.include_router(contacts.router)
+app.include_router(stationmeta.router)
+app.include_router(timeseries.router)
+app.include_router(data.router)
+
diff --git a/variables/__init__.py b/toardb/utils/__init__.py
similarity index 100%
rename from variables/__init__.py
rename to toardb/utils/__init__.py
diff --git a/utils/database.py b/toardb/utils/database.py
similarity index 100%
rename from utils/database.py
rename to toardb/utils/database.py
diff --git a/toardb/variables/__init__.py b/toardb/variables/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/variables/crud.py b/toardb/variables/crud.py
similarity index 100%
rename from variables/crud.py
rename to toardb/variables/crud.py
diff --git a/variables/fixtures/variables.json b/toardb/variables/fixtures/variables.json
similarity index 100%
rename from variables/fixtures/variables.json
rename to toardb/variables/fixtures/variables.json
diff --git a/variables/models.py b/toardb/variables/models.py
similarity index 100%
rename from variables/models.py
rename to toardb/variables/models.py
diff --git a/variables/schemas.py b/toardb/variables/schemas.py
similarity index 100%
rename from variables/schemas.py
rename to toardb/variables/schemas.py
diff --git a/variables/test_base.py b/toardb/variables/test_base.py
similarity index 95%
rename from variables/test_base.py
rename to toardb/variables/test_base.py
index 71ac0fdf610222a9938d47fbb144fc779c76a69a..a8b05f14a0129f3f2f12a3802f091833c16b9063 100644
--- a/variables/test_base.py
+++ b/toardb/variables/test_base.py
@@ -7,9 +7,10 @@ from sqlalchemy.engine import Engine as Database
 from sqlalchemy.orm import Session
 from sqlalchemy_utils import database_exists, create_database, drop_database
 
-from utils.database import DATABASE_URL
+from toardb.utils.database import DATABASE_URL
 from .models import Base
-from .variables import app, get_db
+from toardb.toardb import app
+from toardb.variables.variables import get_db
 
 url = str(DATABASE_URL+ "_test")
 _db_conn = create_engine(url)
diff --git a/variables/test_variables.py b/toardb/variables/test_variables.py
similarity index 99%
rename from variables/test_variables.py
rename to toardb/variables/test_variables.py
index 1a7027aee919553e0eef6b4c9a0aefcc1995ee1e..c58b2d03aa46c9cd082109a82708536fa1973839 100644
--- a/variables/test_variables.py
+++ b/toardb/variables/test_variables.py
@@ -27,7 +27,7 @@ class TestApps:
         fake_cur = fake_conn.cursor()
         fake_cur.execute("ALTER SEQUENCE variables_id_seq RESTART WITH 1")
         fake_conn.commit()
-        infilename = "variables/fixtures/variables.json"
+        infilename = "toardb/variables/fixtures/variables.json"
         with open(infilename) as f:
             metajson=json.load(f)
             for entry in metajson:
diff --git a/variables/variables.py b/toardb/variables/variables.py
similarity index 74%
rename from variables/variables.py
rename to toardb/variables/variables.py
index 6067934733df94afa710389867144772ad7034d9..dbc633c6a5db77dfc12ded2044edd5f260149c1a 100644
--- a/variables/variables.py
+++ b/toardb/variables/variables.py
@@ -3,12 +3,12 @@ Simple test API for variable management
 """
 
 from typing import List
-from fastapi import FastAPI, Depends, HTTPException
+from fastapi import APIRouter, Depends, HTTPException
 from sqlalchemy.orm import Session
-from variables import crud, schemas
-from utils.database import ToarDbSession
+from toardb.variables import crud, schemas
+from toardb.utils.database import ToarDbSession
 
-app = FastAPI()
+router= APIRouter()
 
 # Dependency
 def get_db():
@@ -20,26 +20,26 @@ def get_db():
 
 
 # plain views to post and get variables
-@app.post('/variables/', response_model=schemas.Variable)
+@router.post('/variables/', response_model=schemas.Variable)
 def create_variable(variable: schemas.VariableCreate, db: Session = Depends(get_db)):
     db_variable = crud.get_variable_by_name(db, name=variable.name)
     if db_variable:
         raise HTTPException(status_code=400, detail="Variable already registered.")
     return crud.create_variable(db=db, variable=variable)
 
-@app.get('/variables/', response_model=List[schemas.Variable])
+@router.get('/variables/', response_model=List[schemas.Variable])
 def get_variables(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
     variables = crud.get_variables(db, skip=skip, limit=limit)
     return variables
 
-@app.get('/variables/{name}', response_model=schemas.Variable)
+@router.get('/variables/{name}', response_model=schemas.Variable)
 def get_variable(name: str, db: Session = Depends(get_db)):
     db_variable = crud.get_variable_by_name(db, name=name)
     if db_variable is None:
         raise HTTPException(status_code=404, detail="Variable not found.")
     return db_variable
 
-@app.get('/variables/id/{variable_id}', response_model=schemas.Variable)
+@router.get('/variables/id/{variable_id}', response_model=schemas.Variable)
 def get_variable(variable_id: int, db: Session = Depends(get_db)):
     db_variable = crud.get_variable(db, variable_id=variable_id)
     if db_variable is None: