diff --git a/octobot/community/authentication.py b/octobot/community/authentication.py
index d3029536af..816ff21fa9 100644
--- a/octobot/community/authentication.py
+++ b/octobot/community/authentication.py
@@ -64,9 +64,11 @@ class CommunityAuthentication(authentication.Authenticator):
     SESSION_HEADER = "X-Session"
     GQL_AUTHORIZATION_HEADER = "Authorization"
 
-    def __init__(self, feed_url, config=None):
+    def __init__(self, feed_url, config=None, backend_url=None, backend_key=None):
         super().__init__()
         self.feed_url = feed_url
+        self.backend_url = backend_url or identifiers_provider.IdentifiersProvider.BACKEND_URL
+        self.backend_key = backend_key or identifiers_provider.IdentifiersProvider.BACKEND_KEY
         self.configuration_storage = supabase_backend.SyncConfigurationStorage(config)
         self.supabase_client = self._create_client()
         self.user_account = community_user_account.CommunityUserAccount()
@@ -80,10 +82,11 @@ def __init__(self, feed_url, config=None):
         self._fetch_account_task = None
 
     @staticmethod
-    def create(configuration: commons_configuration.Configuration):
+    def create(configuration: commons_configuration.Configuration, **kwargs):
         return CommunityAuthentication.instance(
             None,
             config=configuration,
+            **kwargs,
         )
 
     def update(self, configuration: commons_configuration.Configuration):
@@ -178,8 +181,8 @@ def _supports_mock():
 
     def _create_client(self):
         return supabase_backend.CommunitySupabaseClient(
-            identifiers_provider.IdentifiersProvider.BACKEND_URL,
-            identifiers_provider.IdentifiersProvider.BACKEND_KEY,
+            self.backend_url,
+            self.backend_key,
             self.configuration_storage
         )
 
diff --git a/octobot/community/supabase_backend/community_supabase_client.py b/octobot/community/supabase_backend/community_supabase_client.py
index 9799b3b33b..976441051a 100644
--- a/octobot/community/supabase_backend/community_supabase_client.py
+++ b/octobot/community/supabase_backend/community_supabase_client.py
@@ -59,6 +59,7 @@ def __init__(
         self.event_loop = None
         super().__init__(supabase_url, supabase_key, options=options)
         self.is_admin = False
+        self.production_anon_client = None
 
     async def sign_in(self, email: str, password: str) -> None:
         try:
@@ -346,7 +347,8 @@ async def fetch_candles_history(
         self, exchange: str, symbol: str, time_frame: commons_enums.TimeFrames,
         first_open_time: float, last_open_time: float
     ) -> list:
-        historical_candles = await self._fetch_paginated_signals_history(
+        historical_candles = await self._fetch_paginated_history(
+            await self.get_production_anon_client(),
             "temp_ohlcv_history",
             "timestamp, open, high, low, close, volume",
             {
@@ -363,26 +365,25 @@ async def fetch_candles_history(
     async def fetch_gpt_signal(
         self, exchange: str, symbol: str, time_frame: commons_enums.TimeFrames, timestamp: float, version: str
     ) -> str:
-        signals = (
-            await self.table("temp_chatgpt_signals").select("signal").match(
-                {
-                    "timestamp": timestamp,
-                    "exchange_internal_name": exchange,
-                    "symbol": symbol,
-                    "time_frame": time_frame.value,
-                    "metadata->>version": version,
-                },
-            ).execute()
-        ).data
+        signals = (await (await self.get_production_anon_client()).table("temp_chatgpt_signals").select("signal").match(
+            {
+                "timestamp": self.get_formatted_time(timestamp),
+                "exchange_internal_name": exchange,
+                "symbol": symbol,
+                "time_frame": time_frame.value,
+                "metadata->>version": version,
+            },
+        ).execute()).data
         if signals:
-            return signals[0]["content"]
+            return signals[0]["signal"]["content"]
         return ""
 
     async def fetch_gpt_signals_history(
         self, exchange: str, symbol: str, time_frame: commons_enums.TimeFrames,
         first_open_time: float, last_open_time: float, version: str
     ) -> dict:
-        historical_signals = await self._fetch_paginated_signals_history(
+        historical_signals = await self._fetch_paginated_history(
+            await self.get_production_anon_client(),
             "temp_chatgpt_signals",
             "timestamp, signal",
             {
@@ -397,8 +398,16 @@ async def fetch_gpt_signals_history(
         )
         return self._format_gpt_signals(historical_signals)
 
-    async def _fetch_paginated_signals_history(
-        self, table_name: str, select: str, matcher: dict,
+    async def get_production_anon_client(self):
+        if self.production_anon_client is None:
+            self.production_anon_client = await self.init_other_postgrest_client(
+                supabase_url=constants.COMMUNITY_PRODUCTION_BACKEND_URL,
+                supabase_key=constants.COMMUNITY_PRODUCTION_BACKEND_KEY,
+            )
+        return self.production_anon_client
+
+    async def _fetch_paginated_history(
+        self, client, table_name: str, select: str, matcher: dict,
         time_interval: float, first_open_time: float, last_open_time: float
     ) -> list:
         total_elements_count = (last_open_time - first_open_time) // time_interval
@@ -409,7 +418,7 @@ async def _fetch_paginated_signals_history(
         request_count = 0
         while request_count < max_requests_count:
             request = (
-                self.table(table_name).select(select)
+                client.table(table_name).select(select)
                 .match(matcher).gte(
                     "timestamp", self.get_formatted_time(first_open_time)
                 ).lte(
@@ -525,3 +534,13 @@ def get_parsed_time(str_time: str) -> datetime.datetime:
 
     async def _get_user(self) -> gotrue.User:
         return self.auth.get_user().user
+
+    async def close(self):
+        await super().close()
+        if self.production_anon_client is not None:
+            try:
+                await self.production_anon_client.aclose()
+            except RuntimeError:
+                # happens when the event loop is closed already
+                pass
+            self.production_anon_client = None
diff --git a/octobot/community/supabase_backend/supabase_client.py b/octobot/community/supabase_backend/supabase_client.py
index 777f48f0bb..37a38ab3be 100644
--- a/octobot/community/supabase_backend/supabase_client.py
+++ b/octobot/community/supabase_backend/supabase_client.py
@@ -14,6 +14,7 @@
 #  You should have received a copy of the GNU General Public
 #  License along with OctoBot. If not, see <https://www.gnu.org/licenses/>.
 import contextlib
+import copy
 import typing
 import storage3
 import storage3.constants
@@ -61,8 +62,8 @@ def _init_postgrest_client(
         rest_url: str,
         supabase_key: str,
         headers: typing.Dict[str, str],
-        schema: str,
         timeout,    # skip typing to avoid httpx import
+        schema: str = "public",
     ) -> postgrest.AsyncPostgrestClient:
         """Private helper for creating an instance of the Postgrest client."""
         # Override to use postgrest.AsyncPostgrestClient and allow async requests
@@ -96,21 +97,33 @@ def table(self, table_name: str) -> postgrest.AsyncRequestBuilder:  # typing ove
         return self.from_(table_name)
 
     @contextlib.asynccontextmanager
-    async def other_postgres_client(self, schema):
-        other_postgres: postgrest.AsyncPostgrestClient = None
+    async def other_postgres_client(self, supabase_url: str = None, supabase_key: str = None, schema: str = "public"):
+        other_postgres = None
         try:
-            other_postgres = AuthenticatedAsyncSupabaseClient._init_postgrest_client(
-                rest_url=self.rest_url,
-                supabase_key=self.supabase_key,
-                headers=self.options.headers,
-                schema=schema,
-                timeout=self.options.postgrest_client_timeout,
+            other_postgres = await self.init_other_postgrest_client(
+                supabase_url=supabase_url, supabase_key=supabase_key, schema=schema
             )
             yield other_postgres
         finally:
             if other_postgres is not None:
                 await other_postgres.aclose()
 
+    async def init_other_postgrest_client(
+        self, supabase_url: str = None, supabase_key: str = None, schema: str = "public"
+    ) -> postgrest.AsyncPostgrestClient:
+        supabase_key = supabase_key or self.supabase_key
+        headers = self.options.headers
+        if supabase_key != self.supabase_key:
+            headers = copy.deepcopy(postgrest.constants.DEFAULT_POSTGREST_CLIENT_HEADERS)
+            headers.update(self._format_auth_headers(supabase_key, supabase_key))
+        return AuthenticatedAsyncSupabaseClient._init_postgrest_client(
+            rest_url=f"{supabase_url}/rest/v1" if supabase_url else self.rest_url,
+            supabase_key=supabase_key,
+            headers=headers,
+            timeout=self.options.postgrest_client_timeout,
+            schema=schema,
+        )
+
     async def close(self):
         # timer has to be stopped, there is no public stop api
         if self.auth._refresh_token_timer:
@@ -148,9 +161,12 @@ def _use_auth_session(self, event: gotrue.AuthChangeEvent, _):
     def _get_auth_headers(self):
         """Helper method to get auth headers."""
         # What's the corresponding method to get the token
+        return self._format_auth_headers(self.supabase_key, self._get_auth_key())
+
+    def _format_auth_headers(self, supabase_key, auth_token):
         return {
-            "apiKey": self.supabase_key,
-            "Authorization": f"Bearer {self._get_auth_key()}",
+            "apiKey": supabase_key,
+            "Authorization": f"Bearer {auth_token}",
         }
 
     def _get_auth_key(self):
diff --git a/octobot/constants.py b/octobot/constants.py
index 80516dcfcc..491a79b02d 100644
--- a/octobot/constants.py
+++ b/octobot/constants.py
@@ -63,11 +63,10 @@
 OCTOBOT_COMMUNITY_LANDING_URL = os.getenv("COMMUNITY_SERVER_URL", "https://octobot.cloud")
 OCTOBOT_COMMUNITY_URL = os.getenv("COMMUNITY_SERVER_URL", "https://app.octobot.cloud")
 OCTOBOT_COMMUNITY_RECOVER_PASSWORD_URL = OCTOBOT_COMMUNITY_URL
-# todo use real production db
+# default env
 COMMUNITY_BACKEND_URL = os.getenv("COMMUNITY_BACKEND_URL", "https://nwhpvrguwcihhizrnyoe.supabase.co")
 COMMUNITY_BACKEND_KEY = os.getenv("COMMUNITY_BACKEND_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im53aHB2cmd1d2NpaGhpenJueW9lIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTU2NDQxMDcsImV4cCI6MjAxMTIyMDEwN30.AILcgv0l6hl_0IUEPlWh1wiu9RIpgrkGZGERM5uXftE")
 
-
 # staging env SHOULD ONLY BE USED THROUGH CommunityIdentifiersProvider
 STAGING_OCTOBOT_COMMUNITY_LANDING_URL = os.getenv("COMMUNITY_SERVER_URL", "https://beta.octobot.cloud")
 STAGING_OCTOBOT_COMMUNITY_URL = os.getenv("COMMUNITY_SERVER_URL", "https://app-beta.octobot.cloud/")
@@ -75,7 +74,9 @@
 STAGING_COMMUNITY_BACKEND_URL = os.getenv("COMMUNITY_BACKEND_URL", "https://wmfkgvgzokyzhvxowbyg.supabase.co")
 STAGING_COMMUNITY_BACKEND_KEY = os.getenv("COMMUNITY_BACKEND_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6IndtZmtndmd6b2t5emh2eG93YnlnIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTE0NDA1MTEsImV4cCI6MjAwNzAxNjUxMX0.YZQl7LYgvnzO_Jizs0UKfPEaqPoV2EwhjunH8gime8o")
 
-
+# production env, ignored by CommunityIdentifiersProvider
+COMMUNITY_PRODUCTION_BACKEND_URL = os.getenv("COMMUNITY_PRODUCTION_BACKEND_URL", COMMUNITY_BACKEND_URL)
+COMMUNITY_PRODUCTION_BACKEND_KEY = os.getenv("COMMUNITY_PRODUCTION_BACKEND_KEY", COMMUNITY_BACKEND_KEY)
 
 CONFIG_COMMUNITY = "community"
 CONFIG_COMMUNITY_BOT_ID = "bot_id"