diff --git a/mapping_provider/__init__.py b/mapping_provider/__init__.py
index e48147a4a4ff068ef4ef81152d18ac77138bcefc..8660a8800eb6e9442eaa353215589a46772c44fc 100644
--- a/mapping_provider/__init__.py
+++ b/mapping_provider/__init__.py
@@ -5,12 +5,16 @@ Default entry point for the FastAPI application.
 from fastapi import FastAPI
 
 from mapping_provider.api import common, map
-
+from mapping_provider import config
+from mapping_provider import environment
 
 def create_app() -> FastAPI:
     """
     Creates the FastAPI application instance, with routers attached.
     """
+    environment.setup_logging()
+    environment.setup_sentry(config.load().sentry)
+
     app = FastAPI(
         title="Mapping provider",
         description="Mapping provider endpoints for GÉANT maps",
diff --git a/mapping_provider/api/map.py b/mapping_provider/api/map.py
index 7616ab4ff0fb72c35fa5de5843dd1b2af316f9e3..a2b8461b13323a022fd89729faf36cc10a5daf7e 100644
--- a/mapping_provider/api/map.py
+++ b/mapping_provider/api/map.py
@@ -5,6 +5,8 @@ import requests
 from fastapi import APIRouter
 from pydantic import BaseModel
 
+from mapping_provider import config
+
 router = APIRouter()
 
 
@@ -161,11 +163,11 @@ def get_sites() -> SiteList:
     """
     handler for /sites
     """
-
     # TODO: catch/handle the usual exceptions
 
+    app_params = config.load()
     rv = requests.get(
-        f'{INPROV_API_URL_TODO}/map/sites',
+        f'{app_params.inventory}/map/sites',
         headers={'Accept': 'application/json'})
     rv.raise_for_status()
     site_list_json = rv.json()
@@ -183,8 +185,9 @@ def get_routers() -> RouterList:
 
     # TODO: catch/handle the usual exceptions
 
+    app_params = config.load()
     rv = requests.get(
-        f'{INPROV_API_URL_TODO}/map/routers',
+        f'{app_params.inventory}/map/routers',
         headers={'Accept': 'application/json'})
     rv.raise_for_status()
     router_list_json = rv.json()
@@ -202,8 +205,9 @@ def get_trunks() -> ServiceList:
 
     # TODO: catch/handle the usual exceptions
 
+    app_params = config.load()
     rv = requests.get(
-        f'{INPROV_API_URL_TODO}/map/services/IP TRUNK',
+        f'{app_params.inventory}/map/services/IP TRUNK',
         headers={'Accept': 'application/json'})
     rv.raise_for_status()
     service_list_json = rv.json()
diff --git a/mapping_provider/config.py b/mapping_provider/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..c61b44aee8a46c5eaa2f913285fbafe7beb59158
--- /dev/null
+++ b/mapping_provider/config.py
@@ -0,0 +1,65 @@
+import os
+from pydantic import BaseModel, Field, HttpUrl
+
+class SentryConfig(BaseModel):
+    dsn: str
+    environment: str
+    level: str = Field(
+        default='error',
+        pattern="^(debug|info|warning|error)$")
+
+    # @field_validator('level')
+    # @classmethod
+    # def validate_level(cls, v):
+    #     if v not in ['debug', 'info', 'warning', 'error']:
+    #         raise ValueError('level must be one of: debug, info, warning, error')
+    #     return v
+
+class Configuration(BaseModel):
+    sentry: SentryConfig
+    inventory: HttpUrl
+
+
+# CONFIG_SCHEMA = {
+#     '$schema': 'https://json-schema.org/draft/2020-12/schema',
+
+#     'definitions': {
+#         'sentry-info': {
+#             'type': 'object',
+#             'properties': {
+#                 'dsn': {'type': 'string'},
+#                 'environment': {'type': 'string'},
+#                 'level': {
+#                     'type': 'string',
+#                     'enum': ['debug', 'info', 'warning', 'error'],
+#                     'default': DEFAULT_SENTRY_LOG_LEVEL
+#                 }
+#             },
+#             'required': ['dsn'],
+#             'additionalProperties': False,
+#         },
+#     },
+
+#     'type': 'object',
+#     'properties': {
+#         'sentry': {'$ref': '#/definitions/sentry-info'},
+#         'inventory': {
+#             'type': 'string',
+#             'format': 'uri',
+#         }
+#     },
+#     'required': ['sentry', 'inventory'],
+#     'additionalProperties': False
+# }
+
+
+def load():
+    """
+    Loads, validates and returns configuration parameters from
+    the file named in the environment variable 'SETTINGS_FILENAME'.
+
+    :return:
+    """
+    assert 'SETTINGS_FILENAME' in os.environ
+    with open(os.environ['SETTINGS_FILENAME']) as f:
+        return Configuration.model_validate_json(f.read())
diff --git a/mapping_provider/environment.py b/mapping_provider/environment.py
new file mode 100644
index 0000000000000000000000000000000000000000..527ab4b6215a3067c3ec67c88b7ef3cda4070af7
--- /dev/null
+++ b/mapping_provider/environment.py
@@ -0,0 +1,93 @@
+"""
+Environment setup
+===================
+
+.. autofunction:: mapping_provider.environment.setup_logging
+
+.. autofunction:: mapping_provider.environment.setup_sentry
+
+"""
+import json
+import logging.config
+import logging
+import os
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from mapping_provider.config import SentryConfig
+
+import sentry_sdk
+from sentry_sdk.integrations.logging import LoggingIntegration
+
+
+LOGGING_DEFAULT_CONFIG = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'formatters': {
+        'simple': {
+            'format': '%(asctime)s - %(name)s '
+                      '(%(lineno)d) - %(levelname)s - %(message)s'
+        }
+    },
+
+    'handlers': {
+        'console': {
+            'class': 'logging.StreamHandler',
+            'level': 'DEBUG',
+            'formatter': 'simple',
+            'stream': 'ext://sys.stdout'
+        }
+
+    },
+
+    'loggers': {
+        'mapping_provider': {
+            'level': 'DEBUG',
+            'handlers': ['console'],
+            'propagate': False
+        }
+    },
+
+    'root': {
+        'level': 'WARNING',
+        'handlers': ['console']
+    }
+}
+
+
+def setup_logging():
+    """
+    Sets up logging using the configured filename.
+
+    if LOGGING_CONFIG is defined in the environment, use this for
+    the filename, otherwise use LOGGING_DEFAULT_CONFIG
+    """
+    logging_config = LOGGING_DEFAULT_CONFIG
+    if 'LOGGING_CONFIG' in os.environ:
+        filename = os.environ['LOGGING_CONFIG']
+        with open(filename) as f:
+            logging_config = json.load(f)
+
+    logging.config.dictConfig(logging_config)
+
+
+def setup_sentry(sentry_config_params: 'SentryConfig'):
+    """
+    Sets up the sentry instrumentation based on the Configuration.sentry params.
+    """
+    match str(sentry_config_params.level):
+        case 'debug': level = logging.DEBUG
+        case 'info': level = logging.INFO
+        case 'warning': level = logging.WARNING
+        case 'error': level = logging.ERROR
+
+    sentry_sdk.init(
+        dsn=sentry_config_params.dsn,
+        environment=sentry_config_params.environment,
+        integrations=[
+            LoggingIntegration(
+                level=logging.INFO,  # Capture info and above as breadcrumbs
+                event_level=level  # Send records as events
+            ),
+        ],
+    )
diff --git a/requirements.txt b/requirements.txt
index bb2015ee9487eb433ea427c9b1981ce044ad2c78..0c99b1de0cb6985c5f38d93aa260d46242f3c856 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,18 +2,12 @@ fastapi
 uvicorn[standard]
 requests
 jsonschema
+sentry_sdk
 
 httpx  # required for fastapi TestClient
 pytest
 responses
 
-sphinx
-sphinx-rtd-theme
-sphinxcontrib-plantuml
-sphinxcontrib-drawio
-sphinxcontrib-openapi
-
 ruff
 mypy
-tox
 pre-commit
diff --git a/setup.py b/setup.py
index 5e5209c7d2b398fa6ee6b7e28f954dc397cc8133..b0fd259282caceba9920789bbe3e94fc7259e70c 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,10 @@ setup(
     python_requires=">=3.10",
     install_requires=[
         "fastapi",
-        "uvicorn[standard]"
+        "uvicorn[standard]",
+        "requests",
+        "jsonschema",
+        "sentry_sdk",        
     ],
     long_description=open("README.md", encoding="utf-8").read(),
     long_description_content_type="text/markdown",
diff --git a/test/conftest.py b/test/conftest.py
index 30d1064fc524060647411bb2ac20bb73c6991ddb..4e7c4f211775a3d0ff490a372c3df867dec0fc8d 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -1,3 +1,8 @@
+import json
+import os
+import tempfile
+from unittest.mock import patch
+
 import pytest
 from fastapi.testclient import TestClient
 
@@ -5,5 +10,26 @@ from mapping_provider import create_app
 
 
 @pytest.fixture
-def client():
-    return TestClient(create_app())
+def dummy_config():
+    return {
+        'sentry': {
+            'dsn': 'https://token@hostname.geant.org:1111/a/b',
+            'environment': 'unit tests'
+        },
+        'inventory': 'https://dummy-hostname.dummy.domain'
+    }
+
+
+@pytest.fixture
+def dummy_config_filename(dummy_config):
+    with tempfile.NamedTemporaryFile(delete=False) as f:
+        f.write(json.dumps(dummy_config).encode('utf-8'))
+        f.flush()
+        yield f.name
+
+
+@pytest.fixture
+def client(dummy_config_filename):
+    os.environ['SETTINGS_FILENAME'] = dummy_config_filename
+    with patch('sentry_sdk.init') as _mock_sentry_init:
+        return TestClient(create_app())
diff --git a/tox.ini b/tox.ini
index 2a820fee2d3f0b473e8ae995c0be5289a8fff683..6cab18c91010822224274a53fba412a9b6931858 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,9 +9,9 @@ commands = ruff check mapping_provider test
 [testenv:typecheck]
 description = Type-check code with mypy
 deps =
-   mypy
-   types-jsonschema
-   types-requests
+    mypy
+    types-jsonschema
+    types-requests
 commands = mypy mapping_provider
 
 [testenv:docs]