diff --git a/README.md b/README.md
index e5a3dbec..51cbe782 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,8 @@ pip install saagieapi==<version>
 | >= 2023.02                  | >= 2.6.0               |
 | >= 2023.03                  | >= 2.7.0               |
 | >= 2023.04                  | >= 2.9.0               |
-| >= 2023.05                  | >= 2.10.0               |
+| >= 2023.05                  | >= 2.10.0              |
+| >= 2024.01                  | >= 2.11.0              |
 
 ## Contributing
 
diff --git a/docs/index.rst b/docs/index.rst
index c87f7922..a1db9fb4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -25,6 +25,7 @@ Compatibility with your Saagie platform
 >= 2023.03                  >= 2.7.0
 >= 2023.04                  >= 2.9.0
 >= 2023.05                  >= 2.10.0
+>= 2024.01                  >= 2.11.0
 =========================== ======================
 
 Usage
diff --git a/saagieapi/jobs/gql_queries.py b/saagieapi/jobs/gql_queries.py
index 719ff940..42a1bef9 100644
--- a/saagieapi/jobs/gql_queries.py
+++ b/saagieapi/jobs/gql_queries.py
@@ -62,6 +62,7 @@
                 deletable
                 reasons
             }
+            sourceUrl
         }
         category
         technology {
@@ -231,13 +232,25 @@
 """
 
 GQL_CREATE_JOB = """
-mutation createJobMutation($projectId: UUID!, $name: String!, $description: String, $category: String!,
-                           $isScheduled: Boolean!, $cronScheduling: Cron, $scheduleTimezone: TimeZone
-                           $technologyId: UUID!, $extraTechnology: ExtraTechnologyInput,
-                           $alerting: JobPipelineAlertingInput, $resources: JobResourceInput,
-                           $releaseNote: String, $runtimeVersion: String, $commandLine: String,
-                           $dockerInfo: JobDockerInput, $file: Upload) {
-    createJob(job: {
+mutation createJobMutation($projectId: UUID!, 
+                            $name: String!, 
+                            $description: String, 
+                            $category: String!,
+                            $isScheduled: Boolean!, 
+                            $cronScheduling: Cron, 
+                            $scheduleTimezone: TimeZone
+                            $technologyId: UUID!, 
+                            $extraTechnology: ExtraTechnologyInput,
+                            $alerting: JobPipelineAlertingInput, 
+                            $resources: JobResourceInput,
+                            $releaseNote: String, 
+                            $runtimeVersion: String, 
+                            $commandLine: String,
+                            $dockerInfo: JobDockerInput, 
+                            $file: Upload, 
+                            $sourceUrl: String) {
+    createJob(
+        job: {
             projectId: $projectId
             name: $name
             description: $description
@@ -259,6 +272,7 @@
             commandLine: $commandLine
             extraTechnology: $extraTechnology
             dockerInfo: $dockerInfo
+            sourceUrl: $sourceUrl
         }
         file: $file
     ){
@@ -273,9 +287,15 @@
 """
 
 GQL_UPGRADE_JOB = """
-mutation addJobVersionMutation($jobId: UUID!, $releaseNote: String, $runtimeVersion: String, $commandLine: String,
-                               $extraTechnology: ExtraTechnologyInput,
-                               $usePreviousArtifact: Boolean, $dockerInfo: JobDockerInput, $file: Upload) {
+mutation addJobVersionMutation($jobId: UUID!, 
+                                $releaseNote: String, 
+                                $runtimeVersion: String, 
+                                $commandLine: String,
+                                $extraTechnology: ExtraTechnologyInput,
+                                $usePreviousArtifact: Boolean, 
+                                $dockerInfo: JobDockerInput, 
+                                $file: Upload,
+                                $sourceUrl: String) {
     addJobVersion(
         jobId: $jobId
         jobVersion: {
@@ -285,6 +305,7 @@
             extraTechnology: $extraTechnology
             dockerInfo: $dockerInfo
             usePreviousArtifact: $usePreviousArtifact
+            sourceUrl: $sourceUrl
         }
         file: $file
     ){
@@ -355,6 +376,7 @@
                 deletable
                 reasons
             }
+            sourceUrl
         }
         category
         technology {
@@ -447,6 +469,7 @@
                 deletable
                 reasons
             }
+            sourceUrl
         }
         category
         technology {
diff --git a/saagieapi/jobs/jobs.py b/saagieapi/jobs/jobs.py
index 1a1d5552..3020d162 100644
--- a/saagieapi/jobs/jobs.py
+++ b/saagieapi/jobs/jobs.py
@@ -581,6 +581,7 @@ def create(
         resources: Dict = None,
         emails: List = None,
         status_list: List = None,
+        source_url: str = "",
     ) -> Dict:
         """Create job in given project
 
@@ -632,6 +633,8 @@ def create(
             Receive an email when the job status change to a specific status
             Each item of the list should be one of these following values: "REQUESTED", "QUEUED",
             "RUNNING", "FAILED", "KILLED", "KILLING", "SUCCEEDED", "UNKNOWN", "AWAITING", "SKIPPED"
+        source_url: str, optional
+            URL of the source code used for the job (link to the commit for example)
 
         Returns
         -------
@@ -657,7 +660,8 @@ def create(
         ...     schedule_timezone='Europe/Paris',
         ...     resources={"cpu": {"request": 0.5, "limit": 2.6}, "memory": {"request": 1.0}},
         ...     emails=['email1@saagie.io', 'email2@saagie.io'],
-        ...     status_list=["FAILED", "KILLED"]
+        ...     status_list=["FAILED", "KILLED"],
+        ...     source_url="",
         ... )
         {
             "data":{
@@ -723,6 +727,9 @@ def create(
         if resources:
             params["resources"] = resources
 
+        if source_url:
+            params["source_url"] = source_url
+
         result = self.__launch_request(file, GQL_CREATE_JOB, params)
         logging.info("✅ Job [%s] successfully created", job_name)
         return result
@@ -869,6 +876,7 @@ def upgrade(
         release_note: str = "",
         extra_technology: str = None,
         extra_technology_version: str = None,
+        source_url: str = "",
     ) -> Dict:
         """Upgrade a job
 
@@ -893,6 +901,8 @@ def upgrade(
             None or the request will not work
         extra_technology_version: str (optional)
             Version of the extra technology. Leave to None when not needed
+        source_url: str (optional)
+            URL of the source code used for the job (link to the commit for example)
 
         Returns
         -------
@@ -952,6 +962,10 @@ def upgrade(
         # Add extra technology parameter if needed
         if extra_technology is not None:
             params["extraTechnology"] = {"language": extra_technology, "version": extra_technology_version}
+
+        if source_url:
+            params["sourceUrl"] = source_url
+
         result = self.__launch_request(file, GQL_UPGRADE_JOB, params)
         logging.info("✅ Job [%s] successfully upgraded", job_id)
         return result
@@ -967,6 +981,7 @@ def upgrade_by_name(
         release_note: str = None,
         extra_technology: str = None,
         extra_technology_version: str = None,
+        source_url: str = "",
     ) -> Dict:
         """Upgrade a job
 
@@ -990,6 +1005,8 @@ def upgrade_by_name(
             Extra technology when needed (spark jobs). If not needed, leave to None or the request will not work
         extra_technology_version: str (optional)
             Version of the extra technology. Leave to None when not needed
+        source_url: str (optional)
+            URL of the source code used for the job (link to the commit for example)
 
         Returns
         -------
@@ -1016,14 +1033,15 @@ def upgrade_by_name(
         }
         """
         return self.upgrade(
-            self.get_id(job_name, project_name),
-            file,
-            use_previous_artifact,
-            runtime_version,
-            command_line,
-            release_note,
-            extra_technology,
-            extra_technology_version,
+            job_id=self.get_id(job_name, project_name),
+            file=file,
+            use_previous_artifact=use_previous_artifact,
+            runtime_version=runtime_version,
+            command_line=command_line,
+            release_note=release_note,
+            extra_technology=extra_technology,
+            extra_technology_version=extra_technology_version,
+            source_url=source_url,
         )
 
     def create_or_upgrade(
@@ -1047,6 +1065,7 @@ def create_or_upgrade(
         resources: Dict = None,
         emails: List = None,
         status_list: List = None,
+        source_url: str = "",
     ) -> Dict:
         """Create or upgrade a job
 
@@ -1091,6 +1110,8 @@ def create_or_upgrade(
             Emails
         status_list: list (optional)
             Status list
+        source_url: str (optional)
+            URL of the source code used for the job (link to the commit for example)
 
         Returns
         -------
@@ -1118,7 +1139,8 @@ def create_or_upgrade(
         ...     schedule_timezone='Europe/Paris',
         ...     resources={"cpu": {"request": 0.5, "limit": 2.6}, "memory": {"request": 1.0}},
         ...     emails=['email1@saagie.io', 'email2@saagie.io'],
-        ...     status_list=["FAILED", "KILLED"]
+        ...     status_list=["FAILED", "KILLED"],
+        ...     source_url="",
         ... )
         {
             "data":{
@@ -1152,6 +1174,7 @@ def create_or_upgrade(
                     release_note=release_note,
                     extra_technology=extra_technology,
                     extra_technology_version=extra_technology_version,
+                    source_url=source_url,
                 )["data"]["addJobVersion"]
             }
 
@@ -1190,6 +1213,7 @@ def create_or_upgrade(
                 "resources": resources,
                 "emails": emails,
                 "status_list": status_list,
+                "source_url": source_url,
             }.items()
             if v is not None  # Remove None values from the dict
         }
diff --git a/saagieapi/pipelines/gql_queries.py b/saagieapi/pipelines/gql_queries.py
index 50154e32..c10ba86e 100644
--- a/saagieapi/pipelines/gql_queries.py
+++ b/saagieapi/pipelines/gql_queries.py
@@ -5,6 +5,7 @@
         pipelines{
             id
             name
+            alias
         }
     }
 }
@@ -19,6 +20,7 @@
         pipelines{
             id
             name
+            alias
             description
             alerting{
                 emails
@@ -106,6 +108,7 @@
     graphPipeline(id: $id){
         id
         name
+        alias
         description
         alerting{
             emails
@@ -199,6 +202,7 @@
     graphPipelineByName(projectId: $projectId, name: $pipelineName) {
         id
         name
+        alias
         description
         alerting{
             emails
@@ -302,7 +306,8 @@
 		 $isScheduled: Boolean, 
 		 $cronScheduling: Cron, 
 		 $scheduleTimezone:TimeZone, 
-		 $hasExecutionVariablesEnabled: Boolean)    {
+		 $hasExecutionVariablesEnabled: Boolean,
+         $alias: String)    {
     editPipeline(pipeline: 
         {
             id: $id
@@ -313,10 +318,12 @@
             cronScheduling: $cronScheduling
             scheduleTimezone: $scheduleTimezone
             hasExecutionVariablesEnabled: $hasExecutionVariablesEnabled
+            alias: $alias
         }
     ){
         id
         name
+        alias
         description
         alerting{
             emails
@@ -380,21 +387,24 @@
                                      $cronScheduling: Cron, 
                                      $scheduleTimezone:TimeZone,
                                      $jobNodes: [JobNodeInput!], 
-                                     $conditionNodes: [ConditionNodeInput!]) {
-    createGraphPipeline(pipeline:    {
-        name: $name
-        description: $description
-        projectId: $projectId
-        releaseNote : $releaseNote
-        alerting: $alerting
-        isScheduled: $isScheduled
-        cronScheduling: $cronScheduling
-        scheduleTimezone: $scheduleTimezone
-        graph: {
-            jobNodes: $jobNodes
-            conditionNodes: $conditionNodes
+                                     $conditionNodes: [ConditionNodeInput!],
+                                     $alias: String!) {
+    createGraphPipeline(
+        pipeline: {
+            name: $name
+            description: $description
+            projectId: $projectId
+            releaseNote : $releaseNote
+            alerting: $alerting
+            isScheduled: $isScheduled
+            cronScheduling: $cronScheduling
+            scheduleTimezone: $scheduleTimezone
+            graph: {
+                jobNodes: $jobNodes
+                conditionNodes: $conditionNodes
+            }
+            alias: $alias
         }
-    }
     ) {
         id
     }
@@ -518,8 +528,8 @@
 """
 
 GQL_DUPLICATE_PIPELINE = """
-mutation duplicatePipeline($pipelineId: UUID!) {
-    duplicatePipeline(originalPipelineId: $pipelineId) {
+mutation duplicatePipeline($pipelineId: UUID!, $duplicateJobs: Boolean) {
+    duplicatePipeline(originalPipelineId: $pipelineId, duplicateJobs: $duplicateJobs) {
         id
         name
     }
diff --git a/saagieapi/pipelines/pipelines.py b/saagieapi/pipelines/pipelines.py
index 7891b212..f7060ea8 100644
--- a/saagieapi/pipelines/pipelines.py
+++ b/saagieapi/pipelines/pipelines.py
@@ -376,6 +376,7 @@ def get_info(
             "graphPipeline": {
                 "id": "5d1999f5-fa70-47d9-9f41-55ad48333629",
                 "name": "Pipeline A",
+                "alias": "Pipeline_A",
                 "description": "My Pipeline A",
                 "alerting": "NULL",
                 "pipelineInstanceCount": 0,
@@ -730,6 +731,7 @@ def create_graph(
         name: str,
         project_id: str,
         graph_pipeline: GraphPipeline,
+        alias: str,
         description: str = "",
         release_note: str = "",
         emails: List[str] = None,
@@ -755,6 +757,8 @@ def create_graph(
                 job_node1.add_next_node(job_node2) # Indicates that the job_node_1 is followed by job_node_2
                 graph_pipeline = GraphPipeline()
                 graph_pipeline.add_root_node(job_node1) # Indicates the pipeline will start with job_node1
+        alias: str
+            Alias of the pipeline
         description : str, optional
             Description of the pipeline
         release_note: str, optional
@@ -827,6 +831,7 @@ def create_graph(
             "releaseNote": release_note,
             "jobNodes": graph_pipeline.list_job_nodes,
             "conditionNodes": graph_pipeline.list_conditions_nodes,
+            "alias": alias,
         }
 
         if cron_scheduling:
@@ -871,7 +876,7 @@ def delete(self, pipeline_id: str) -> Dict:
 
     def upgrade(self, pipeline_id: str, graph_pipeline: GraphPipeline, release_note: str = "") -> Dict:
         """
-        Create a pipeline in a given project
+        Upgrade a pipeline in a given project
 
         Parameters
         ----------
@@ -960,6 +965,7 @@ def edit(
         self,
         pipeline_id: str,
         name: str = None,
+        alias: str = None,
         description: str = None,
         emails: List[str] = None,
         status_list: List[str] = None,
@@ -979,6 +985,9 @@ def edit(
         name : str, optional
             Pipeline name,
             if not filled, defaults to current value, else it will change the pipeline name
+        alias : str, optional
+            Alias of the pipeline
+            if not filled, defaults to current value, else it will change the alias of the pipeline
         description : str, optional
             Description of the pipeline
             if not filled, defaults to current value, else it will change the description of the pipeline
@@ -1019,6 +1028,7 @@ def edit(
             "editPipeline":{
                 "id": "ca79c5c8-2e57-4a35-bcfc-5065f0ee901c",
                 "name": "Amazing Pipeline 2",
+                "alias": "Amazing_Pipeline_2",
                 "description": "",
                 "alerting": None,
                 "isScheduled": True,
@@ -1033,6 +1043,7 @@ def edit(
         params = {
             "id": pipeline_id,
             "name": name or previous_pipeline_info["name"],
+            "alias": alias or previous_pipeline_info["alias"],
             "description": description or previous_pipeline_info["description"],
         }
 
@@ -1068,6 +1079,7 @@ def edit(
     def create_or_upgrade(
         self,
         name: str,
+        alias: str,
         project_id: str,
         graph_pipeline: GraphPipeline,
         description: str = None,
@@ -1085,6 +1097,8 @@ def create_or_upgrade(
         ----------
         name : str
             Pipeline name
+        alias : str
+            Alias of the pipeline
         project_id : str
             UUID of your project (see README on how to find it)
         graph_pipeline : GraphPipeline
@@ -1163,6 +1177,7 @@ def create_or_upgrade(
                 "editPipeline": self.edit(
                     pipeline_id=pipeline_id,
                     name=name,
+                    alias=alias,
                     description=description,
                     emails=emails,
                     status_list=status_list,
@@ -1182,6 +1197,7 @@ def create_or_upgrade(
             k: v
             for k, v in {
                 "name": name,
+                "alias": alias,
                 "project_id": project_id,
                 "graph_pipeline": graph_pipeline,
                 "description": description,
@@ -1504,6 +1520,7 @@ def import_from_json(self, json_file: str, project_id: str) -> bool:
             graph_pipeline.list_conditions_nodes = parse_version_conditions(version)
             res = self.create_graph(
                 name=pipeline_name,
+                alias=pipeline_info["alias"],
                 project_id=project_id,
                 graph_pipeline=graph_pipeline,
                 description=pipeline_info["description"],
@@ -1779,13 +1796,15 @@ def delete_instances_by_date(
         logging.info("✅ Instances of pipeline [%s] successfully deleted", pipeline_id)
         return result
 
-    def duplicate(self, pipeline_id):
+    def duplicate(self, pipeline_id, duplicate_jobs: bool = False) -> Dict:
         """Duplicate a given pipeline
 
         Parameters
         ----------
         pipeline_id : str
             UUID of your pipeline (see README on how to find it)
+        duplicate_jobs : bool, optional
+            If True, duplicate the jobs of the pipeline, else only the pipeline
 
         Returns
         -------
diff --git a/saagieapi/storages/gql_queries.py b/saagieapi/storages/gql_queries.py
index 99308ced..a491fa97 100644
--- a/saagieapi/storages/gql_queries.py
+++ b/saagieapi/storages/gql_queries.py
@@ -25,6 +25,9 @@
             ...appVersionFieldInformation
         }
     }
+    originalVolumeId
+    duplicationStatus
+    isLocked
 }
 
 query projectQuery($id: UUID!, $minimal: Boolean!) {
@@ -51,6 +54,9 @@
         linkedApp {
             id
         }
+        originalVolumeId
+        duplicationStatus
+        isLocked
     }
 }
 """
@@ -118,6 +124,21 @@
                 ...appVersionFieldInformation
             }
         }
+        originalVolumeId
+        duplicationStatus
+        isLocked
+    }
+}
+"""
+
+GQL_DUPLICATE_STORAGE = """
+mutation duplicateVolume($volumeId: UUID!) {
+    duplicateVolume(originalVolumeId: $volumeId) {
+        id
+        name
+        originalVolumeId
+        duplicationStatus
+        isLocked
     }
 }
 """
diff --git a/saagieapi/storages/storages.py b/saagieapi/storages/storages.py
index 0f1611d1..f6e93932 100644
--- a/saagieapi/storages/storages.py
+++ b/saagieapi/storages/storages.py
@@ -71,7 +71,10 @@ def list_for_project(
                             "number":1,
                             "volumesWithPath":[]
                         }
-                    }
+                    },
+                    "originalVolumeId":"None",
+                    "duplicationStatus":"None",
+                    "isLocked":false
                 },
                 {
                     "id":"905d8441-8955-444f-a333-19d7c6fe6274",
@@ -107,7 +110,10 @@ def list_for_project(
                                 }
                             ]
                         }
-                    }
+                    },
+                    "originalVolumeId":"None",
+                    "duplicationStatus":"None",
+                    "isLocked":false
                 }
             ]
         }
@@ -179,7 +185,10 @@ def get_info(self, project_id: str, storage_id: str) -> Dict:
                     "number":1,
                     "volumesWithPath":[]
                 }
-            }
+            },
+            "originalVolumeId":"None",
+            "duplicationStatus":"None",
+            "isLocked":false
         }
         """  # pylint: disable=line-too-long
         storages = self.list_for_project(project_id)["project"]["volumes"]
@@ -241,7 +250,10 @@ def get(self, storage_id: str) -> Dict:
                         "number":1,
                         "volumesWithPath":[]
                     }
-                }
+                },
+                "originalVolumeId":"None",
+                "duplicationStatus":"None",
+                "isLocked":false
             }
         }
         """  # pylint: disable=line-too-long
@@ -294,7 +306,10 @@ def create(
                 "description":"storage description",
                 "creationDate":"2022-09-12T13:52:19.523Z",
                 "creator":"user.name",
-                "linkedApp":"None"
+                "linkedApp":"None",
+                "originalVolumeId":"None",
+                "duplicationStatus":"None",
+                "isLocked":false
             }
         }
         """
@@ -487,3 +502,33 @@ def move(self, storage_id: str, target_platform_id: int, target_project_id: str)
                 "targetProjectId": target_project_id,
             },
         )
+
+    def duplicate(self, storage_id: str):
+        """Duplicate a storage
+
+        Parameters
+        ----------
+        storage_id : str
+            UUID of your storage (see README on how to find it)
+
+        Returns
+        -------
+        dict
+            Dict of the duplicated storage with its new id
+
+        Examples
+        --------
+        >>> saagie_api.storages.duplicate(storage_id='fdb43a11-ccec-4b10-9690-2b83fbd7eb93')
+        {
+            'duplicateVolume': {
+                id: '29cf1b80-6b9c-47bc-a06c-c20897257097',
+                name: 'storage name (copy)',
+                originalVolumeId: 'fdb43a11-ccec-4b10-9690-2b83fbd7eb93',
+                isLocked: true,
+            }
+        }
+        """
+        return self.saagie_api.client.execute(
+            query=gql(GQL_DUPLICATE_STORAGE),
+            variable_values={"volumeId": storage_id},
+        )
diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py
index 6ad830f2..109acc9e 100644
--- a/tests/integration/conftest.py
+++ b/tests/integration/conftest.py
@@ -164,6 +164,7 @@ def create_graph_pipeline(create_job, create_global_project):
     graph_pipeline.add_root_node(job_node1)
 
     name = "TEST_VIA_API"
+    alias = "ALIAS_TEST_VIA_API"
     description = "DESCRIPTION_TEST_VIA_API"
     cron_scheduling = "0 0 * * *"
     schedule_timezone = "Pacific/Fakaofo"
@@ -172,6 +173,7 @@ def create_graph_pipeline(create_job, create_global_project):
         project_id=conf.project_id,
         graph_pipeline=graph_pipeline,
         name=name,
+        alias=alias,
         description=description,
         cron_scheduling=cron_scheduling,
         schedule_timezone=schedule_timezone,
diff --git a/tests/integration/pipelines_integration_test.py b/tests/integration/pipelines_integration_test.py
index 3db21a89..44183521 100644
--- a/tests/integration/pipelines_integration_test.py
+++ b/tests/integration/pipelines_integration_test.py
@@ -81,6 +81,7 @@ def test_edit_graph_pipeline(create_then_delete_graph_pipeline, create_global_pr
         pipeline_id, _ = create_then_delete_graph_pipeline
         pipeline_input = {
             "name": "test_edit_graph_pipeline",
+            "alias": "test_edit_alias_graph_pipeline",
             "description": "test_edit_graph_pipeline",
             "is_scheduled": True,
             "cron_scheduling": "0 0 * * *",
@@ -91,6 +92,7 @@ def test_edit_graph_pipeline(create_then_delete_graph_pipeline, create_global_pr
         conf.saagie_api.pipelines.edit(
             pipeline_id,
             name=pipeline_input["name"],
+            alias=pipeline_input["alias"],
             description=pipeline_input["description"],
             is_scheduled=pipeline_input["is_scheduled"],
             cron_scheduling=pipeline_input["cron_scheduling"],
@@ -100,6 +102,7 @@ def test_edit_graph_pipeline(create_then_delete_graph_pipeline, create_global_pr
         pipeline_info = conf.saagie_api.pipelines.get_info(pipeline_id)
         to_validate = {
             "name": pipeline_info["graphPipeline"]["name"],
+            "alias": pipeline_info["graphPipeline"]["alias"],
             "description": pipeline_info["graphPipeline"]["description"],
             "alerting": None,
             "is_scheduled": pipeline_info["graphPipeline"]["isScheduled"],
@@ -240,6 +243,7 @@ def test_rollback_pipeline_version(create_then_delete_graph_pipeline, create_glo
     def test_create_or_upgrade_pipeline(delete_pipeline, create_job, create_global_project):
         conf = create_global_project
         pipeline_name = delete_pipeline
+        pipeline_alias = pipeline_name.replace(" ", "_")
 
         job_id = create_job
         job_node1 = JobNode(job_id)
@@ -263,6 +267,7 @@ def test_create_or_upgrade_pipeline(delete_pipeline, create_job, create_global_p
 
         pipeline_create = conf.saagie_api.pipelines.create_or_upgrade(
             name=pipeline_name,
+            alias=pipeline_alias,
             project_id=conf.project_id,
             description="Description pipeline dev test",
             release_note="First release",
@@ -280,6 +285,7 @@ def test_create_or_upgrade_pipeline(delete_pipeline, create_job, create_global_p
 
         pipeline_upgrade = conf.saagie_api.pipelines.create_or_upgrade(
             name=pipeline_name,
+            alias=pipeline_alias,
             project_id=conf.project_id,
             description="Description pipeline dev test",
             release_note="Second release",
diff --git a/tests/integration/resources/import/pipelines/without-existing-jobs/pipeline.json b/tests/integration/resources/import/pipelines/without-existing-jobs/pipeline.json
index 5aa51fa5..e25b84ca 100644
--- a/tests/integration/resources/import/pipelines/without-existing-jobs/pipeline.json
+++ b/tests/integration/resources/import/pipelines/without-existing-jobs/pipeline.json
@@ -1,6 +1,7 @@
 {
     "id": "bd17ddcc-b932-4917-a2a4-17ea582bb3fe",
     "name": "Pipeline dev test 2",
+    "alias": "Pipeline_dev_test_2",
     "description": "Description pipeline dev test",
     "alerting": {
         "emails": [
diff --git a/tests/integration/resources/import/project/apps/from-catalog/app.json b/tests/integration/resources/import/project/apps/from-catalog/app.json
index 59795e69..0ef8288f 100644
--- a/tests/integration/resources/import/project/apps/from-catalog/app.json
+++ b/tests/integration/resources/import/project/apps/from-catalog/app.json
@@ -38,7 +38,7 @@
                         "name": "storage Jupyter Notebook (0)",
                         "creator": "guillaume.prevost",
                         "description": "Autogenerated storage from app installation for \"/notebooks-dir\" path in \"Jupyter Notebook\" app.",
-                        "size": "128 MB",
+                        "size": "1 GB",
                         "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                         "creationDate": "2022-08-26T13:12:05.363Z",
                         "linkedApp": {
@@ -77,7 +77,7 @@
                     "name": "storage Jupyter Notebook (0)",
                     "creator": "guillaume.prevost",
                     "description": "Autogenerated storage from app installation for \"/notebooks-dir\" path in \"Jupyter Notebook\" app.",
-                    "size": "128 MB",
+                    "size": "1 GB",
                     "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                     "creationDate": "2022-08-26T13:12:05.363Z",
                     "linkedApp": {
diff --git a/tests/integration/resources/import/project/apps/from-scratch/app.json b/tests/integration/resources/import/project/apps/from-scratch/app.json
index 76675a52..33d60336 100644
--- a/tests/integration/resources/import/project/apps/from-scratch/app.json
+++ b/tests/integration/resources/import/project/apps/from-scratch/app.json
@@ -41,7 +41,7 @@
                         "name": "storage Jupyter Notebook (1) (0)",
                         "creator": "guillaume.prevost",
                         "description": "Autogenerated storage from app installation for \"/notebooks-dir\" path in \"Jupyter Notebook (1)\" app.",
-                        "size": "64 MB",
+                        "size": "1 GB",
                         "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                         "creationDate": "2022-08-29T08:18:29.962Z",
                         "linkedApp": {
@@ -81,7 +81,7 @@
                         "name": "test",
                         "creator": "guillaume.prevost",
                         "description": "test description",
-                        "size": "128 MB",
+                        "size": "1 GB",
                         "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                         "creationDate": "2022-08-29T08:02:11.811Z",
                         "linkedApp": {
@@ -149,7 +149,7 @@
                         "name": "test",
                         "creator": "guillaume.prevost",
                         "description": "test description",
-                        "size": "128 MB",
+                        "size": "1 GB",
                         "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                         "creationDate": "2022-08-29T08:02:11.811Z",
                         "linkedApp": {
@@ -190,7 +190,7 @@
                     "name": "test",
                     "creator": "guillaume.prevost",
                     "description": "test description",
-                    "size": "128 MB",
+                    "size": "1 GB",
                     "projectId": "a3a1d433-6c8b-4ae0-9769-db09e3c9e52a",
                     "creationDate": "2022-08-29T08:02:11.811Z",
                     "linkedApp": {
@@ -332,7 +332,7 @@
     },
     "linkedVolumes": [
         {
-            "size": "128 MB"
+            "size": "1 GB"
         },
         {
             "size": "64 MB"
diff --git a/tests/integration/resources/import/project/pipelines/with-existing-jobs/pipeline.json b/tests/integration/resources/import/project/pipelines/with-existing-jobs/pipeline.json
index d2ebd81f..747fc598 100644
--- a/tests/integration/resources/import/project/pipelines/with-existing-jobs/pipeline.json
+++ b/tests/integration/resources/import/project/pipelines/with-existing-jobs/pipeline.json
@@ -1,6 +1,7 @@
 {
     "id": "bd17ddcc-b932-4917-a2a4-17ea582bb3fe",
     "name": "Pipeline dev test 2",
+    "alias": "Pipeline_dev_test_2",
     "description": "Description pipeline dev test",
     "alerting": {
         "emails": [
diff --git a/tests/integration/resources/import/project/pipelines/without-alerting/pipeline.json b/tests/integration/resources/import/project/pipelines/without-alerting/pipeline.json
index e8a5c175..9b5e2199 100644
--- a/tests/integration/resources/import/project/pipelines/without-alerting/pipeline.json
+++ b/tests/integration/resources/import/project/pipelines/without-alerting/pipeline.json
@@ -1,6 +1,7 @@
 {
     "id": "bd17ddcc-b932-4917-a2a4-17ea582bb3fe",
     "name": "Pipeline test without alerting",
+    "alias": "Pipeline_test_without_alerting",
     "description": "Description pipeline dev test",
     "alerting": null,
     "pipelineInstanceCount": 0,
diff --git a/tests/integration/storages_integration_test.py b/tests/integration/storages_integration_test.py
index 664bc5de..5d2ed748 100644
--- a/tests/integration/storages_integration_test.py
+++ b/tests/integration/storages_integration_test.py
@@ -13,7 +13,7 @@ def create_storage(create_global_project):
         storage = conf.saagie_api.storages.create(
             project_id=conf.project_id,
             storage_name=storage_name,
-            storage_size="128 MB",
+            storage_size="1 GB",
             storage_description="Be happy",
         )
         return storage["createVolume"]
@@ -65,7 +65,7 @@ def test_edit_storage(create_then_delete_storage, create_global_project):
         storage_input = {
             "id": storage["id"],
             "name": "storage new name",
-            "size": "128.0 MB",
+            "size": "1.0 GB",
             "description": "storage new description",
         }
 
@@ -223,3 +223,16 @@ def test_get_storage_info(create_then_delete_storage, create_global_project):
         del result["volume"]["creationDate"]
 
         assert storage == result["volume"]
+
+    @staticmethod
+    def test_duplicate_storage(create_then_delete_storage, create_global_project):
+        conf = create_global_project
+
+        storage = create_then_delete_storage
+
+        # needed to let the time to the storage to be created and ready in the orchestrator
+        time.sleep(5)
+
+        result = conf.saagie_api.storages.duplicate(storage_id=storage["id"])
+
+        assert result["duplicateVolume"]["originalVolumeId"] == storage["id"]
diff --git a/tests/unit/resources/schema.graphqls b/tests/unit/resources/schema.graphqls
index 779eb544..f076c514 100644
--- a/tests/unit/resources/schema.graphqls
+++ b/tests/unit/resources/schema.graphqls
@@ -283,6 +283,14 @@ type Query {
   # This endpoint allows to retrieve a pipeline with versions in linear or graph format.
   graphPipelineByName(projectId: UUID!, name: String!): Pipeline
 
+
+  # Get a pipeline's details from its projectId and alias.
+  #
+  # You can only get a pipeline's details if you have at least the viewer role in the project associated to the pipeline or in all projects.
+  #
+  # This endpoint allows to retrieve a pipeline with versions in linear or graph format.
+  graphPipelineByAlias(projectId: UUID!, name: String!): Pipeline!
+
   # List users by realm.
   usersByRealm: [UserEmail]
 
@@ -608,10 +616,15 @@ type Mutation {
   # You can only delete a pipeline if you have the global Super-Admin role.
   deletePipeline(id: UUID!): Boolean!
 
-  # Duplicate a pipeline in the same project. Its jobs is not duplicated and only current version of pipeline is duplicated.
+  # Duplicate a pipeline in the same project. Only current version of pipeline is duplicated.
+  # By default, pipeline's jobs are not duplicated.
   #
+  # **Fields validation:**
+  # - originalPipelineId: (required) must exist, must be deletable, must not be in migration state.
+  # - duplicateJobs: (optional, false by default) if true, duplicate all jobs (only each current version) associated with the current version of pipeline.
+
   # You can only duplicate a pipeline if you have at least role editor on the project associated to the pipeline or on all projects.
-  duplicatePipeline(originalPipelineId: UUID!): Pipeline!
+  duplicatePipeline(originalPipelineId: UUID!, duplicateJobs: Boolean): Pipeline!
 
   # Move pipeline with its jobs from a project to another. The target can be in another platform.
   # Also move all jobs associated with this pipeline.
@@ -710,7 +723,7 @@ type Mutation {
   # **Fields validation:**
   # - name: must be unique (case insensitive) in the project, shorter than 255 characters and cannot be empty.
   # - project: must exist. Use 'projects' query to list all projects.
-  # - size: size in MB, must be between 64MB and the maximum value set by your administrator.
+  # - size: size in MB, must be between the step (eq. minimum) and the maximum value set by your administrator.
   createVolume(volume: VolumeInput!): Volume!
 
   # Delete a volume.
@@ -738,6 +751,11 @@ type Mutation {
   # UUID of the volume moved in the target
   moveVolume(volumeId: UUID!, targetPlatformId: Int!, targetProjectId: UUID!): UUID!
 
+  # Duplicate a volume in the same project.
+  #
+  # You can only duplicate a volume if you have at least role editor on the project associated to the volume or on all projects.
+  duplicateVolume(originalVolumeId: UUID!): Volume!
+
   # Create a Connection related to a project.
   # **Fields validation:**
   # - name: must be unique (case insensitive) in the project, shorter than 255 characters and cannot be empty.
@@ -838,6 +856,7 @@ input JobVersionInput {
   doesUseGPU: Boolean
   connectionId: UUID
   externalJobParams: [ExternalJobParamInput!]
+  sourceUrl: String
 }
 
 input ExternalJobParamInput {
@@ -956,6 +975,7 @@ input SecurityGroupInput {
 
 input PipelineInput {
   name: String!
+  alias: String!
   description: String
   alerting: JobPipelineAlertingInput
   projectId: UUID!
@@ -969,6 +989,7 @@ input PipelineInput {
 # Input to create a pipeline with a Directed Acyclic Graph
 input GraphPipelineInput {
   name: String!
+  alias: String!
   description: String
   alerting: JobPipelineAlertingInput
   # Enable or disable modification of variables in jobs during execution
@@ -1044,6 +1065,7 @@ input NodePositionInput {
 input PipelineEditionInput {
   id: UUID!
   name: String
+  alias: String
   description: String
   alerting: JobPipelineAlertingInput
   # Enable or disable modification of variables in jobs during execution
@@ -1176,6 +1198,10 @@ type Volume {
   migrationPlatformId: Int
   migrationProjectId: UUID
   migrationVolumeId: UUID
+  duplicationStatus: DuplicationStatus
+  duplicationTargetId: UUID
+  originalVolumeId: UUID
+  isLocked: Boolean
 }
 
 type Job {
@@ -1533,6 +1559,7 @@ type JobVersion {
   doesUseGPU: Boolean @deprecated(reason: "Use Job.doesUseGPU instead")
   connectionId: UUID
   externalJobParams: [ExternalJobParam!]
+  sourceUrl: String
 }
 
 type JobVersionDeletableState {
@@ -1661,6 +1688,7 @@ type SecurityGroup {
 type Pipeline {
   id: UUID!
   name: String!
+  alias: String!
   description: String
   alerting: JobPipelineAlerting
   # Indicates if modification of variables in jobs of this pipeline is enable or disable during execution
@@ -1720,10 +1748,8 @@ type OtherPipelineWithSharedJob {
 type PipelineVersion {
   number: Int!
   releaseNote: String
-  # List of jobs in a linear pipeline
-  #
-  # This field is deprecated and used only for linear pipelines, use `graph` instead
-  jobs: [Job!] @deprecated(reason: "Use graph instead")
+  # Set of jobs in a linear pipeline (soon deprecated) or graph pipeline
+  jobs: [Job!]
   # Corresponds to the graph of jobs and conditions of a pipeline in graph format
   # For a linear pipeline, it returns a graph corresponding to the list of jobs.
   graph: PipelineGraph
@@ -2086,6 +2112,12 @@ enum MigrationStatus {
   FAILED
 }
 
+enum DuplicationStatus {
+  DUPLICATION_OUT,
+  DUPLICATION_IN,
+  FAILED
+}
+
 enum TriggerType {
   MANUAL_JOB,
   MANUAL_APP,
