diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 568acb76e5f1ffd08f19df54d5070adf1a179f86..a97e4ad8adb04754593fc73e9aceff0359be3c83 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -148,56 +148,57 @@ The following API resources are available in the group context:
 
 The following API resources are available outside of project and group contexts (including `/users`):
 
-| Resource                                                                                | Available endpoints |
-|:----------------------------------------------------------------------------------------|:--------------------|
-| [Appearance](appearance.md) **(FREE SELF)**                                             | `/application/appearance` |
-| [Applications](applications.md)                                                         | `/applications` |
-| [Audit Events](audit_events.md) **(PREMIUM SELF)**                                      | `/audit_events` |
-| [Avatar](avatar.md)                                                                     | `/avatar` |
-| [Broadcast messages](broadcast_messages.md)                                             | `/broadcast_messages` |
-| [Code snippets](snippets.md)                                                            | `/snippets` |
-| [Custom attributes](custom_attributes.md)                                               | `/users/:id/custom_attributes` (also available for groups and projects) |
-| [Deploy keys](deploy_keys.md)                                                           | `/deploy_keys` (also available for projects) |
-| [Deploy tokens](deploy_tokens.md)                                                       | `/deploy_tokens` (also available for projects and groups) |
-| [Events](events.md)                                                                     | `/events`, `/users/:id/events` (also available for projects) |
-| [Feature flags](features.md)                                                            | `/features` |
-| [Geo Nodes](geo_nodes.md) **(PREMIUM SELF)**                                            | `/geo_nodes` |
-| [Group Activity Analytics](group_activity_analytics.md)                                 | `/analytics/group_activity/{issues_count}` |
-| [Group repository storage moves](group_repository_storage_moves.md) **(PREMIUM SELF)**  | `/group_repository_storage_moves` |
-| [Import repository from GitHub](import.md#import-repository-from-github)                                              | `/import/github` |
-| [Import repository from Bitbucket Server](import.md#import-repository-from-bitbucket-server)                                              | `/import/bitbucket_server` |
-| [Instance clusters](instance_clusters.md) **(FREE SELF)**                               | `/admin/clusters` |
-| [Instance-level CI/CD variables](instance_level_ci_variables.md) **(FREE SELF)**        | `/admin/ci/variables` |
-| [Issues Statistics](issues_statistics.md)                                               | `/issues_statistics` (also available for groups and projects) |
-| [Issues](issues.md)                                                                     | `/issues` (also available for groups and projects) |
-| [Jobs](jobs.md)                                                                         | `/job` |
-| [Keys](keys.md)                                                                         | `/keys` |
-| [License](license.md) **(FREE SELF)**                                                   | `/license` |
-| [Markdown](markdown.md)                                                                 | `/markdown` |
-| [Merge requests](merge_requests.md)                                                     | `/merge_requests` (also available for groups and projects) |
-| [Metrics dashboard annotations](metrics_dashboard_annotations.md)                       | `/environments/:id/metrics_dashboard/annotations`, `/clusters/:id/metrics_dashboard/annotations` |
-| [Namespaces](namespaces.md)                                                             | `/namespaces` |
-| [Notification settings](notification_settings.md)                                       | `/notification_settings` (also available for groups and projects) |
-| [Pages domains](pages_domains.md)                                                       | `/pages/domains` (also available for projects) |
-| [Personal access tokens](personal_access_tokens.md)                                     | `/personal_access_tokens` |
-| [Plan limits](plan_limits.md)                                                           | `/application/plan_limits` |
-| [Project repository storage moves](project_repository_storage_moves.md) **(FREE SELF)** | `/project_repository_storage_moves` |
-| [Projects](projects.md)                                                                 | `/users/:id/projects` (also available for projects) |
-| [Runners](runners.md)                                                                   | `/runners` (also available for projects) |
-| [Search](search.md)                                                                     | `/search` (also available for groups and projects) |
-| [Service Data](usage_data.md)                                                           | `/usage_data` (For GitLab instance [Administrator](../user/permissions.md) users only) |
-| [Settings](settings.md) **(FREE SELF)**                                                 | `/application/settings` |
-| [Sidekiq metrics](sidekiq_metrics.md) **(FREE SELF)**                                   | `/sidekiq` |
-| [Sidekiq queues administration](admin_sidekiq_queues.md) **(FREE SELF)**                | `/admin/sidekiq/queues/:queue_name` |
-| [Snippet repository storage moves](snippet_repository_storage_moves.md) **(FREE SELF)** | `/snippet_repository_storage_moves` |
-| [Statistics](statistics.md)                                                             | `/application/statistics` |
-| [Suggestions](suggestions.md)                                                           | `/suggestions` |
-| [System hooks](system_hooks.md)                                                         | `/hooks` |
-| [To-dos](todos.md)                                                                      | `/todos` |
-| [Topics](topics.md)                                                                     | `/topics` |
-| [Users](users.md)                                                                       | `/users` |
-| [Validate `.gitlab-ci.yml` file](lint.md)                                               | `/lint` |
-| [Version](version.md)                                                                   | `/version` |
+| Resource                                                                                     | Available endpoints                                                                              |
+|:---------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------|
+| [Appearance](appearance.md) **(FREE SELF)**                                                  | `/application/appearance`                                                                        |
+| [Applications](applications.md)                                                              | `/applications`                                                                                  |
+| [Audit Events](audit_events.md) **(PREMIUM SELF)**                                           | `/audit_events`                                                                                  |
+| [Avatar](avatar.md)                                                                          | `/avatar`                                                                                        |
+| [Broadcast messages](broadcast_messages.md)                                                  | `/broadcast_messages`                                                                            |
+| [Code snippets](snippets.md)                                                                 | `/snippets`                                                                                      |
+| [Code suggestions](code_suggestions.md)                                                      | `/code_suggestions`                                                                              |
+| [Custom attributes](custom_attributes.md)                                                    | `/users/:id/custom_attributes` (also available for groups and projects)                          |
+| [Deploy keys](deploy_keys.md)                                                                | `/deploy_keys` (also available for projects)                                                     |
+| [Deploy tokens](deploy_tokens.md)                                                            | `/deploy_tokens` (also available for projects and groups)                                        |
+| [Events](events.md)                                                                          | `/events`, `/users/:id/events` (also available for projects)                                     |
+| [Feature flags](features.md)                                                                 | `/features`                                                                                      |
+| [Geo Nodes](geo_nodes.md) **(PREMIUM SELF)**                                                 | `/geo_nodes`                                                                                     |
+| [Group Activity Analytics](group_activity_analytics.md)                                      | `/analytics/group_activity/{issues_count}`                                                       |
+| [Group repository storage moves](group_repository_storage_moves.md) **(PREMIUM SELF)**       | `/group_repository_storage_moves`                                                                |
+| [Import repository from GitHub](import.md#import-repository-from-github)                     | `/import/github`                                                                                 |
+| [Import repository from Bitbucket Server](import.md#import-repository-from-bitbucket-server) | `/import/bitbucket_server`                                                                       |
+| [Instance clusters](instance_clusters.md) **(FREE SELF)**                                    | `/admin/clusters`                                                                                |
+| [Instance-level CI/CD variables](instance_level_ci_variables.md) **(FREE SELF)**             | `/admin/ci/variables`                                                                            |
+| [Issues Statistics](issues_statistics.md)                                                    | `/issues_statistics` (also available for groups and projects)                                    |
+| [Issues](issues.md)                                                                          | `/issues` (also available for groups and projects)                                               |
+| [Jobs](jobs.md)                                                                              | `/job`                                                                                           |
+| [Keys](keys.md)                                                                              | `/keys`                                                                                          |
+| [License](license.md) **(FREE SELF)**                                                        | `/license`                                                                                       |
+| [Markdown](markdown.md)                                                                      | `/markdown`                                                                                      |
+| [Merge requests](merge_requests.md)                                                          | `/merge_requests` (also available for groups and projects)                                       |
+| [Metrics dashboard annotations](metrics_dashboard_annotations.md)                            | `/environments/:id/metrics_dashboard/annotations`, `/clusters/:id/metrics_dashboard/annotations` |
+| [Namespaces](namespaces.md)                                                                  | `/namespaces`                                                                                    |
+| [Notification settings](notification_settings.md)                                            | `/notification_settings` (also available for groups and projects)                                |
+| [Pages domains](pages_domains.md)                                                            | `/pages/domains` (also available for projects)                                                   |
+| [Personal access tokens](personal_access_tokens.md)                                          | `/personal_access_tokens`                                                                        |
+| [Plan limits](plan_limits.md)                                                                | `/application/plan_limits`                                                                       |
+| [Project repository storage moves](project_repository_storage_moves.md) **(FREE SELF)**      | `/project_repository_storage_moves`                                                              |
+| [Projects](projects.md)                                                                      | `/users/:id/projects` (also available for projects)                                              |
+| [Runners](runners.md)                                                                        | `/runners` (also available for projects)                                                         |
+| [Search](search.md)                                                                          | `/search` (also available for groups and projects)                                               |
+| [Service Data](usage_data.md)                                                                | `/usage_data` (For GitLab instance [Administrator](../user/permissions.md) users only)           |
+| [Settings](settings.md) **(FREE SELF)**                                                      | `/application/settings`                                                                          |
+| [Sidekiq metrics](sidekiq_metrics.md) **(FREE SELF)**                                        | `/sidekiq`                                                                                       |
+| [Sidekiq queues administration](admin_sidekiq_queues.md) **(FREE SELF)**                     | `/admin/sidekiq/queues/:queue_name`                                                              |
+| [Snippet repository storage moves](snippet_repository_storage_moves.md) **(FREE SELF)**      | `/snippet_repository_storage_moves`                                                              |
+| [Statistics](statistics.md)                                                                  | `/application/statistics`                                                                        |
+| [Suggestions](suggestions.md)                                                                | `/suggestions`                                                                                   |
+| [System hooks](system_hooks.md)                                                              | `/hooks`                                                                                         |
+| [To-dos](todos.md)                                                                           | `/todos`                                                                                         |
+| [Topics](topics.md)                                                                          | `/topics`                                                                                        |
+| [Users](users.md)                                                                            | `/users`                                                                                         |
+| [Validate `.gitlab-ci.yml` file](lint.md)                                                    | `/lint`                                                                                          |
+| [Version](version.md)                                                                        | `/version`                                                                                       |
 
 ## Templates API resources
 
diff --git a/doc/api/code_suggestions.md b/doc/api/code_suggestions.md
new file mode 100644
index 0000000000000000000000000000000000000000..8057686897f79e71009df58e41ea2a917bd0ab52
--- /dev/null
+++ b/doc/api/code_suggestions.md
@@ -0,0 +1,81 @@
+---
+stage: Manage
+group: AI assisted
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Code Suggestions API
+
+Use the Code Suggestions API to access the Code Suggestions feature.
+
+## Create an access token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/404427) in GitLab 16.1.
+
+Creates an access token to access Code Suggestions.
+
+```plaintext
+POST /code_suggestions/tokens
+```
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/code_suggestions/tokens"
+```
+
+Example response:
+
+```json
+{
+    "access_token": "secret-access-token",
+    "expires_in": 3600,
+    "created_at": 1687865199
+}
+```
+
+## Generate code completions (Experiment)
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/415581) in GitLab 16.2 [with a flag](../administration/feature_flags.md) named `code_suggestions_completion_api`. Disabled by default. This feature is an Experiment.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available.
+On GitLab.com, this feature is not available.
+This feature is not ready for production use.
+
+Use the AI abstraction layer to generate code completions.
+
+```plaintext
+POST /code_suggestions/completions
+```
+
+Requests to this endpoint are proxied directly to the [model gateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#completions). The documentation for the endpoint is currently the SSoT for named parameters.
+
+Authentication to this endpoint requires both a GitLab access token and a Code Suggestions JWT. The access token is used to authenticate the user and the JWT is used to authenticate the request to the model gateway.
+
+```shell
+curl --header "Authorization: Bearer <YOUR_ACCESS_TOKEN>" --header "X-Gitlab-Oidc-Token: <TOKEN_GENERATED_FROM_TOKENS_ENDPOINT>" --data "<JSON_BODY>" https://gitlab.example.com/api/v4/code_suggestions/completions
+```
+
+Example body:
+
+The [model gateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#completions) is the SSoT for parameters.
+
+Example response:
+
+```json
+{
+  "id": "id",
+  "model": {
+    "engine": "vertex-ai",
+    "name": "code-gecko"
+  },
+  "object": "text_completion",
+  "created": 1688557841,
+  "choices": [
+    {
+      "text": "\n        if self.is_running:\n            self.speed += increment\n            print(\"The car's speed is now",
+      "index": 0,
+      "finish_reason": "length"
+    }
+  ]
+}
+```
diff --git a/ee/config/feature_flags/development/code_suggestions_completion_api.yml b/ee/config/feature_flags/development/code_suggestions_completion_api.yml
new file mode 100644
index 0000000000000000000000000000000000000000..45215762ed96e0e90261a5f1d0ef0b35dc51ef7a
--- /dev/null
+++ b/ee/config/feature_flags/development/code_suggestions_completion_api.yml
@@ -0,0 +1,8 @@
+---
+name: code_suggestions_completion_api
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125401
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/416371
+milestone: '16.2'
+type: development
+group: group::ai-enablement
+default_enabled: false
diff --git a/ee/lib/api/code_suggestions.rb b/ee/lib/api/code_suggestions.rb
index fd6b5ab8a338c54914789185f0228b7f1545cdef..bb139b549713e3de0172b77660a8a5b3667901ca 100644
--- a/ee/lib/api/code_suggestions.rb
+++ b/ee/lib/api/code_suggestions.rb
@@ -18,6 +18,22 @@ def user_allowed?
         current_user.can?(:access_code_suggestions) && access_code_suggestions_when_proxied_to_saas?
       end
 
+      def model_gateway_headers(headers)
+        token = headers["X-Gitlab-Oidc-Token"]
+
+        telemetry_headers = {
+          'X-GitLab-CS-Accepts' => headers['X-Gitlab-Cs-Accepts'],
+          'X-GitLab-CS-Requests' => headers['X-Gitlab-Cs-Requests'],
+          'X-GitLab-CS-Errors' => headers['X-Gitlab-Cs-Errors']
+        }.compact
+
+        {
+          'X-Gitlab-Authentication-Type' => 'oidc',
+          'Authorization' => "Bearer #{token}",
+          'Content-Type' => 'application/json'
+        }.merge(telemetry_headers)
+      end
+
       # In case the request was proxied from the self-managed instance,
       # we have an extra check on Gitlab.com if FF is enabled for self-managed admin.
       # The FF is used for gradual rollout for handpicked self-managed customers interested to use code suggestions.
@@ -64,6 +80,22 @@ def gitlab_realm
           end
         end
       end
+
+      resources :completions do
+        post do
+          not_found! unless ::Feature.enabled?(:code_suggestions_completion_api, current_user)
+
+          response = ::Gitlab::HTTP.post('https://codesuggestions.gitlab.com/v2/completions', {
+            body: params.except(:private_token).to_json,
+            headers: model_gateway_headers(headers),
+            open_timeout: 3,
+            read_timeout: 5,
+            write_timeout: 5
+          })
+          status response.code
+          response
+        end
+      end
     end
   end
 end
diff --git a/ee/spec/requests/api/code_suggestions_spec.rb b/ee/spec/requests/api/code_suggestions_spec.rb
index 7860a572814a673508aca3abc18b863631bb6937..aaad1f03adeef989b3dab1fafc65863002e3863a 100644
--- a/ee/spec/requests/api/code_suggestions_spec.rb
+++ b/ee/spec/requests/api/code_suggestions_spec.rb
@@ -161,4 +161,122 @@
       end
     end
   end
+
+  describe 'POST /code_suggestions/completions' do
+    let(:access_code_suggestions) { true }
+    let(:headers) do
+      {
+        'X-Gitlab-Authentication-Type' => 'oidc',
+        'X-Gitlab-Oidc-Token' => "JWTTOKEN",
+        'Content-Type' => 'application/json'
+      }
+    end
+
+    let(:body) do
+      {
+        prompt_version: 1,
+        project_path: "gitlab-org/gitlab-shell",
+        project_id: 33191677,
+        current_file: {
+          file_name: "test.py",
+          content_above_cursor: "def is_even(n: int) ->",
+          content_below_cursor: ""
+        }
+      }
+    end
+
+    subject(:post_api) do
+      post api('/code_suggestions/completions', current_user), headers: headers, params: body.to_json
+    end
+
+    before do
+      allow(Ability).to receive(:allowed?).and_call_original
+      allow(Ability).to receive(:allowed?).with(current_user, :access_code_suggestions, :global)
+                                          .and_return(access_code_suggestions)
+      allow(Gitlab).to receive(:org_or_com?).and_return(true)
+    end
+
+    context 'when user is not logged in' do
+      let(:current_user) { nil }
+
+      include_examples 'an unauthorized response'
+    end
+
+    context 'when user does not have access to code suggestions' do
+      let(:access_code_suggestions) { false }
+
+      include_examples 'an unauthorized response'
+    end
+
+    context 'when user is logged in' do
+      let(:current_user) { create(:user) }
+
+      it 'proxies request to code suggestions service' do
+        expect(Gitlab::HTTP).to receive(:post).with(
+          "https://codesuggestions.gitlab.com/v2/completions",
+          {
+            body: body.to_json,
+            headers: {
+              'X-Gitlab-Authentication-Type' => 'oidc',
+              'Authorization' => 'Bearer JWTTOKEN',
+              'Content-Type' => 'application/json'
+            },
+            open_timeout: 3,
+            read_timeout: 5,
+            write_timeout: 5
+          }
+        )
+
+        post_api
+      end
+
+      context 'when feature flag is disabled' do
+        before do
+          stub_feature_flags(code_suggestions_completion_api: false)
+        end
+
+        include_examples 'a response', 'not found' do
+          let(:result) { :not_found }
+          let(:body) do
+            { "message" => "404 Not Found" }
+          end
+        end
+      end
+
+      context 'with telemetry headers' do
+        let(:headers) do
+          {
+            'X-Gitlab-Authentication-Type' => 'oidc',
+            'X-Gitlab-Oidc-Token' => "JWTTOKEN",
+            'Content-Type' => 'application/json',
+            'X-GitLab-CS-Accepts' => 'accepts',
+            'X-GitLab-CS-Requests' => "requests",
+            'X-GitLab-CS-Errors' => 'errors'
+          }
+        end
+
+        it 'proxies request to code suggestions service' do
+          expect(Gitlab::HTTP).to receive(:post).with(
+            "https://codesuggestions.gitlab.com/v2/completions",
+            {
+              body: body.to_json,
+              headers: {
+                'X-Gitlab-Authentication-Type' => 'oidc',
+                'Authorization' => 'Bearer JWTTOKEN',
+                'Content-Type' => 'application/json',
+                'X-GitLab-CS-Accepts' => 'accepts',
+                'X-GitLab-CS-Requests' => "requests",
+                'X-GitLab-CS-Errors' => 'errors'
+              },
+              open_timeout: 3,
+              read_timeout: 5,
+              write_timeout: 5
+            }
+          )
+
+          post_api
+        end
+      end
+    end
+  end
 end