diff --git a/app/graphql/types/ml/candidate_metadata_type.rb b/app/graphql/types/ml/candidate_metadata_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b2cccb47bc5636965f545c15699113ea2ed5f9fb
--- /dev/null
+++ b/app/graphql/types/ml/candidate_metadata_type.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Types
+  module Ml
+    # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+    class CandidateMetadataType < ::Types::BaseObject
+      graphql_name 'MlCandidateMetadata'
+      description 'Metadata for a candidate in the model registry'
+
+      connection_type_class Types::LimitedCountableConnectionType
+
+      field :id, ::Types::GlobalIDType[::Ml::CandidateMetadata], null: false, description: 'ID of the metadata.'
+
+      field :name, ::GraphQL::Types::String,
+        null: true,
+        description: 'Name of the metadata entry.'
+
+      field :value, ::GraphQL::Types::String,
+        null: false,
+        description: 'Value set for the metadata entry.'
+    end
+    # rubocop: enable Graphql/AuthorizeTypes
+  end
+end
diff --git a/app/graphql/types/ml/candidate_metric_type.rb b/app/graphql/types/ml/candidate_metric_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b0cb9ca18e80955df96dc23315cf7d0b37828992
--- /dev/null
+++ b/app/graphql/types/ml/candidate_metric_type.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Types
+  module Ml
+    # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+    class CandidateMetricType < ::Types::BaseObject
+      graphql_name 'MlCandidateMetric'
+      description 'Metric for a candidate in the model registry'
+
+      connection_type_class Types::LimitedCountableConnectionType
+
+      field :id, ::Types::GlobalIDType[::Ml::CandidateMetric], null: false, description: 'ID of the metric.'
+
+      field :name, ::GraphQL::Types::String,
+        null: true,
+        description: 'Name of the metric.'
+
+      field :step, ::GraphQL::Types::Int,
+        null: false,
+        description: 'Step at which the metric was measured.'
+
+      field :value, ::GraphQL::Types::Float,
+        null: false,
+        description: 'Value set for the metric.'
+    end
+    # rubocop: enable Graphql/AuthorizeTypes
+  end
+end
diff --git a/app/graphql/types/ml/candidate_param_type.rb b/app/graphql/types/ml/candidate_param_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e73e176c4e5ef4221304e8e1e018718bf1b568dd
--- /dev/null
+++ b/app/graphql/types/ml/candidate_param_type.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Types
+  module Ml
+    # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver
+    class CandidateParamType < ::Types::BaseObject
+      graphql_name 'MlCandidateParam'
+      description 'Parameter for a candidate in the model registry'
+
+      connection_type_class Types::LimitedCountableConnectionType
+
+      field :id, ::Types::GlobalIDType[::Ml::CandidateParam], null: false, description: 'ID of the parameter.'
+
+      field :name, ::GraphQL::Types::String,
+        null: true,
+        description: 'Name of the parameter.'
+
+      field :value, ::GraphQL::Types::String,
+        null: false,
+        description: 'Value set for the parameter.'
+    end
+    # rubocop: enable Graphql/AuthorizeTypes
+  end
+end
diff --git a/app/graphql/types/ml/candidate_type.rb b/app/graphql/types/ml/candidate_type.rb
index 1c6ce26b9cee8924668a7739c3e6906543fb5b74..9367d0995d3167a107edd5d718298dd246b3c60c 100644
--- a/app/graphql/types/ml/candidate_type.rb
+++ b/app/graphql/types/ml/candidate_type.rb
@@ -31,6 +31,18 @@ class CandidateType < ::Types::BaseObject
 
       field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
 
+      field :params, ::Types::Ml::CandidateParamType.connection_type,
+        null: false,
+        description: 'Parameters for the candidate.'
+
+      field :metrics, ::Types::Ml::CandidateMetricType.connection_type,
+        null: false,
+        description: 'Metrics for the candidate.'
+
+      field :metadata, ::Types::Ml::CandidateMetadataType.connection_type,
+        null: false,
+        description: 'Metadata entries for the candidate.'
+
       field :ci_job, ::Types::Ci::JobType,
         null: true,
         description: 'CI information about the job that created the candidate.'
diff --git a/app/graphql/types/ml/model_version_type.rb b/app/graphql/types/ml/model_version_type.rb
index 771ff2491887a5841d710dc9567d06ecfa5d2f31..30443f537ac8b706c2b467fe210994436821cfa0 100644
--- a/app/graphql/types/ml/model_version_type.rb
+++ b/app/graphql/types/ml/model_version_type.rb
@@ -14,6 +14,10 @@ class ModelVersionType < ::Types::BaseObject
       field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
       field :version, ::GraphQL::Types::String, null: false, description: 'Name of the version.'
 
+      field :package_id, ::Types::GlobalIDType[::Packages::Package],
+        null: false,
+        description: 'Package for model version artifacts.'
+
       field :candidate, ::Types::Ml::CandidateType,
         null: false,
         description: 'Metrics, params and metadata for the model version.'
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 53d7c081ad8ad02d5d3806d69784e152265e02e8..e6c66c6cdc4d0d94dede7ffdf467236e8aaddadb 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -12547,6 +12547,117 @@ The edge type for [`MlCandidate`](#mlcandidate).
 | <a id="mlcandidateedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
 | <a id="mlcandidateedgenode"></a>`node` | [`MlCandidate`](#mlcandidate) | The item at the end of the edge. |
 
+#### `MlCandidateMetadataConnection`
+
+The connection type for [`MlCandidateMetadata`](#mlcandidatemetadata).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetadataconnectionedges"></a>`edges` | [`[MlCandidateMetadataEdge]`](#mlcandidatemetadataedge) | A list of edges. |
+| <a id="mlcandidatemetadataconnectionnodes"></a>`nodes` | [`[MlCandidateMetadata]`](#mlcandidatemetadata) | A list of nodes. |
+| <a id="mlcandidatemetadataconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+##### Fields with arguments
+
+###### `MlCandidateMetadataConnection.count`
+
+Limited count of collection. Returns limit + 1 for counts greater than the limit.
+
+Returns [`Int!`](#int).
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetadataconnectioncountlimit"></a>`limit` | [`Int`](#int) | Limit value to be applied to the count query. Default is 1000. |
+
+#### `MlCandidateMetadataEdge`
+
+The edge type for [`MlCandidateMetadata`](#mlcandidatemetadata).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetadataedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="mlcandidatemetadataedgenode"></a>`node` | [`MlCandidateMetadata`](#mlcandidatemetadata) | The item at the end of the edge. |
+
+#### `MlCandidateMetricConnection`
+
+The connection type for [`MlCandidateMetric`](#mlcandidatemetric).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetricconnectionedges"></a>`edges` | [`[MlCandidateMetricEdge]`](#mlcandidatemetricedge) | A list of edges. |
+| <a id="mlcandidatemetricconnectionnodes"></a>`nodes` | [`[MlCandidateMetric]`](#mlcandidatemetric) | A list of nodes. |
+| <a id="mlcandidatemetricconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+##### Fields with arguments
+
+###### `MlCandidateMetricConnection.count`
+
+Limited count of collection. Returns limit + 1 for counts greater than the limit.
+
+Returns [`Int!`](#int).
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetricconnectioncountlimit"></a>`limit` | [`Int`](#int) | Limit value to be applied to the count query. Default is 1000. |
+
+#### `MlCandidateMetricEdge`
+
+The edge type for [`MlCandidateMetric`](#mlcandidatemetric).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetricedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="mlcandidatemetricedgenode"></a>`node` | [`MlCandidateMetric`](#mlcandidatemetric) | The item at the end of the edge. |
+
+#### `MlCandidateParamConnection`
+
+The connection type for [`MlCandidateParam`](#mlcandidateparam).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidateparamconnectionedges"></a>`edges` | [`[MlCandidateParamEdge]`](#mlcandidateparamedge) | A list of edges. |
+| <a id="mlcandidateparamconnectionnodes"></a>`nodes` | [`[MlCandidateParam]`](#mlcandidateparam) | A list of nodes. |
+| <a id="mlcandidateparamconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+##### Fields with arguments
+
+###### `MlCandidateParamConnection.count`
+
+Limited count of collection. Returns limit + 1 for counts greater than the limit.
+
+Returns [`Int!`](#int).
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidateparamconnectioncountlimit"></a>`limit` | [`Int`](#int) | Limit value to be applied to the count query. Default is 1000. |
+
+#### `MlCandidateParamEdge`
+
+The edge type for [`MlCandidateParam`](#mlcandidateparam).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidateparamedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="mlcandidateparamedgenode"></a>`node` | [`MlCandidateParam`](#mlcandidateparam) | The item at the end of the edge. |
+
 #### `MlModelConnection`
 
 The connection type for [`MlModel`](#mlmodel).
@@ -24257,9 +24368,49 @@ Candidate for a model version in the model registry.
 | <a id="mlcandidateeid"></a>`eid` | [`String!`](#string) | MLflow uuid for the candidate. |
 | <a id="mlcandidateid"></a>`id` | [`MlCandidateID!`](#mlcandidateid) | ID of the candidate. |
 | <a id="mlcandidateiid"></a>`iid` | [`Int!`](#int) | IID of the candidate scoped to project. |
+| <a id="mlcandidatemetadata"></a>`metadata` | [`MlCandidateMetadataConnection!`](#mlcandidatemetadataconnection) | Metadata entries for the candidate. (see [Connections](#connections)) |
+| <a id="mlcandidatemetrics"></a>`metrics` | [`MlCandidateMetricConnection!`](#mlcandidatemetricconnection) | Metrics for the candidate. (see [Connections](#connections)) |
 | <a id="mlcandidatename"></a>`name` | [`String`](#string) | Name of the candidate. |
+| <a id="mlcandidateparams"></a>`params` | [`MlCandidateParamConnection!`](#mlcandidateparamconnection) | Parameters for the candidate. (see [Connections](#connections)) |
 | <a id="mlcandidatestatus"></a>`status` | [`String`](#string) | Candidate status. |
 
+### `MlCandidateMetadata`
+
+Metadata for a candidate in the model registry.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetadataid"></a>`id` | [`MlCandidateMetadataID!`](#mlcandidatemetadataid) | ID of the metadata. |
+| <a id="mlcandidatemetadataname"></a>`name` | [`String`](#string) | Name of the metadata entry. |
+| <a id="mlcandidatemetadatavalue"></a>`value` | [`String!`](#string) | Value set for the metadata entry. |
+
+### `MlCandidateMetric`
+
+Metric for a candidate in the model registry.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidatemetricid"></a>`id` | [`MlCandidateMetricID!`](#mlcandidatemetricid) | ID of the metric. |
+| <a id="mlcandidatemetricname"></a>`name` | [`String`](#string) | Name of the metric. |
+| <a id="mlcandidatemetricstep"></a>`step` | [`Int!`](#int) | Step at which the metric was measured. |
+| <a id="mlcandidatemetricvalue"></a>`value` | [`Float!`](#float) | Value set for the metric. |
+
+### `MlCandidateParam`
+
+Parameter for a candidate in the model registry.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mlcandidateparamid"></a>`id` | [`MlCandidateParamID!`](#mlcandidateparamid) | ID of the parameter. |
+| <a id="mlcandidateparamname"></a>`name` | [`String`](#string) | Name of the parameter. |
+| <a id="mlcandidateparamvalue"></a>`value` | [`String!`](#string) | Value set for the parameter. |
+
 ### `MlModel`
 
 Machine learning model in the model registry.
@@ -24310,6 +24461,7 @@ Version of a machine learning model.
 | <a id="mlmodelversioncandidate"></a>`candidate` | [`MlCandidate!`](#mlcandidate) | Metrics, params and metadata for the model version. |
 | <a id="mlmodelversioncreatedat"></a>`createdAt` | [`Time!`](#time) | Date of creation. |
 | <a id="mlmodelversionid"></a>`id` | [`MlModelVersionID!`](#mlmodelversionid) | ID of the model version. |
+| <a id="mlmodelversionpackageid"></a>`packageId` | [`PackagesPackageID!`](#packagespackageid) | Package for model version artifacts. |
 | <a id="mlmodelversionversion"></a>`version` | [`String!`](#string) | Name of the version. |
 
 ### `MonthlyUsage`
@@ -34424,6 +34576,24 @@ A `MlCandidateID` is a global ID. It is encoded as a string.
 
 An example `MlCandidateID` is: `"gid://gitlab/Ml::Candidate/1"`.
 
+### `MlCandidateMetadataID`
+
+A `MlCandidateMetadataID` is a global ID. It is encoded as a string.
+
+An example `MlCandidateMetadataID` is: `"gid://gitlab/Ml::CandidateMetadata/1"`.
+
+### `MlCandidateMetricID`
+
+A `MlCandidateMetricID` is a global ID. It is encoded as a string.
+
+An example `MlCandidateMetricID` is: `"gid://gitlab/Ml::CandidateMetric/1"`.
+
+### `MlCandidateParamID`
+
+A `MlCandidateParamID` is a global ID. It is encoded as a string.
+
+An example `MlCandidateParamID` is: `"gid://gitlab/Ml::CandidateParam/1"`.
+
 ### `MlModelID`
 
 A `MlModelID` is a global ID. It is encoded as a string.
diff --git a/spec/graphql/types/ml/candidate_metadata_type_spec.rb b/spec/graphql/types/ml/candidate_metadata_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..719739d76f691b5f882c4fb5cd82692c16e4ae19
--- /dev/null
+++ b/spec/graphql/types/ml/candidate_metadata_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlCandidateMetadata'], feature_category: :mlops do
+  it 'has the expected fields' do
+    expected_fields = %w[id name value]
+
+    expect(described_class).to include_graphql_fields(*expected_fields)
+  end
+end
diff --git a/spec/graphql/types/ml/candidate_metric_type_spec.rb b/spec/graphql/types/ml/candidate_metric_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f5c345b819b9fae02eb2db3b3a8780f1a4ae83ef
--- /dev/null
+++ b/spec/graphql/types/ml/candidate_metric_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlCandidateMetric'], feature_category: :mlops do
+  it 'has the expected fields' do
+    expected_fields = %w[id name value step]
+
+    expect(described_class).to include_graphql_fields(*expected_fields)
+  end
+end
diff --git a/spec/graphql/types/ml/candidate_param_type_spec.rb b/spec/graphql/types/ml/candidate_param_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a16b6a6428bff722c6bcb0401a873fbc6f9ae668
--- /dev/null
+++ b/spec/graphql/types/ml/candidate_param_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlCandidateParam'], feature_category: :mlops do
+  it 'has the expected fields' do
+    expected_fields = %w[id name value]
+
+    expect(described_class).to include_graphql_fields(*expected_fields)
+  end
+end
diff --git a/spec/graphql/types/ml/candidate_type_spec.rb b/spec/graphql/types/ml/candidate_type_spec.rb
index 11a3e46ecc86c973558612ecb3974eca29de7b82..41219b0b09f6cb65fcb4f7327b447c887bb63cf1 100644
--- a/spec/graphql/types/ml/candidate_type_spec.rb
+++ b/spec/graphql/types/ml/candidate_type_spec.rb
@@ -10,6 +10,9 @@
   let_it_be(:candidate) do
     model_version.candidate.tap do |c|
       c.update!(ci_build: create(:ci_build, pipeline: pipeline, user: current_user))
+      c.metrics = [create(:ml_candidate_metrics, candidate: c)]
+      c.params = [create(:ml_candidate_params, candidate: c)]
+      c.metadata = [create(:ml_candidate_metadata, candidate: c)]
     end
   end
 
@@ -33,6 +36,21 @@
                   showPath
                   artifactPath
                 }
+                metrics {
+                  nodes {
+                    id
+                  }
+                }
+                params {
+                  nodes {
+                    id
+                  }
+                }
+                metadata {
+                  nodes {
+                    id
+                  }
+                }
               }
             }
           }
@@ -59,6 +77,27 @@
       '_links' => {
         'showPath' => "/#{project.full_path}/-/ml/candidates/#{model_version.candidate.iid}",
         'artifactPath' => "/#{project.full_path}/-/packages/#{model_version.package_id}"
+      },
+      'metrics' => {
+        'nodes' => [
+          {
+            'id' => "gid://gitlab/Ml::CandidateMetric/#{candidate.metrics.first.id}"
+          }
+        ]
+      },
+      'params' => {
+        'nodes' => [
+          {
+            'id' => "gid://gitlab/Ml::CandidateParam/#{candidate.params.first.id}"
+          }
+        ]
+      },
+      'metadata' => {
+        'nodes' => [
+          {
+            'id' => "gid://gitlab/Ml::CandidateMetadata/#{candidate.metadata.first.id}"
+          }
+        ]
       }
     })
   end
diff --git a/spec/graphql/types/ml/model_version_type_spec.rb b/spec/graphql/types/ml/model_version_type_spec.rb
index 16d4e2350a45d844d28cda592061ddd425adff71..b77c4d77791f5c4b398b3aa6685eebc783b5a20a 100644
--- a/spec/graphql/types/ml/model_version_type_spec.rb
+++ b/spec/graphql/types/ml/model_version_type_spec.rb
@@ -15,6 +15,7 @@
             latestVersion {
               id
               version
+              packageId
               candidate {
                 id
               }
@@ -33,7 +34,7 @@
   subject(:data) { GitlabSchema.execute(query, context: { current_user: project.owner }).as_json }
 
   it 'includes all fields' do
-    expected_fields = %w[id version created_at _links candidate]
+    expected_fields = %w[id version created_at _links candidate package_id]
 
     expect(described_class).to include_graphql_fields(*expected_fields)
   end
@@ -44,6 +45,7 @@
     expect(version_data).to eq({
       'id' => "gid://gitlab/Ml::ModelVersion/#{model_version.id}",
       'version' => model_version.version,
+      'packageId' => "gid://gitlab/Packages::Package/#{model_version.package_id}",
       'candidate' => {
         'id' => "gid://gitlab/Ml::Candidate/#{model_version.candidate.id}"
       },