diff --git a/changelogs/unreleased/19439-api-file-sha56-and-head.yml b/changelogs/unreleased/19439-api-file-sha56-and-head.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4bc1e560631676dbbf857bf001f8aa7ec4f56e62
--- /dev/null
+++ b/changelogs/unreleased/19439-api-file-sha56-and-head.yml
@@ -0,0 +1,5 @@
+---
+title: Add SHA256 and HEAD on File API
+merge_request: 19439
+author: ahmet2mir
+type: added
diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md
index c29dc22e12de40ab969158dddbeb0aab830ef051..49fb9bc141dad5e63e42a1bb47eb8b690b3c323d 100644
--- a/doc/api/repository_files.md
+++ b/doc/api/repository_files.md
@@ -27,6 +27,7 @@ Example response:
   "size": 1476,
   "encoding": "base64",
   "content": "IyA9PSBTY2hlbWEgSW5mb3...",
+  "content_sha256": "4c294617b60715c1d218e61164a3abd4808a4284cbc30e6728a01ad9aada4481",
   "ref": "master",
   "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
   "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
@@ -39,6 +40,36 @@ Parameters:
 - `file_path` (required) - Url encoded full path to new file. Ex. lib%2Fclass%2Erb
 - `ref` (required) - The name of branch, tag or commit
 
+NOTE: **Note:**
+`blob_id` is the blob sha, see [repositories - Get a blob from repository](repositories.md#get-a-blob-from-repository)
+
+In addition to the `GET` method, you can also use `HEAD` to get just file metadata.
+
+```
+HEAD /projects/:id/repository/files/:file_path
+```
+
+```bash
+curl --head --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb?ref=master'
+```
+
+Example response:
+
+```text
+HTTP/1.1 200 OK
+...
+X-Gitlab-Blob-Id: 79f7bbd25901e8334750839545a9bd021f0e4c83
+X-Gitlab-Commit-Id: d5a3ff139356ce33e37e73add446f16869741b50
+X-Gitlab-Content-Sha256: 4c294617b60715c1d218e61164a3abd4808a4284cbc30e6728a01ad9aada4481
+X-Gitlab-Encoding: base64
+X-Gitlab-File-Name: key.rb
+X-Gitlab-File-Path: app/models/key.rb
+X-Gitlab-Last-Commit-Id: 570e7b2abdd848b95f2f578043fc23bd6f6fd24d
+X-Gitlab-Ref: master
+X-Gitlab-Size: 1476
+...
+```
+
 ## Get raw file from repository
 
 ```
@@ -54,6 +85,9 @@ Parameters:
 - `file_path` (required) - Url encoded full path to new file. Ex. lib%2Fclass%2Erb
 - `ref` (required) - The name of branch, tag or commit
 
+NOTE: **Note:**
+Like [Get file from repository](repository_files.md#get-file-from-repository) you can use `HEAD` to get just file metadata.
+
 ## Create new file in repository
 
 ```
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 1598d3c00b82048ca825d846e530dd416a6fe7fd..29d7489bd7c8e1fd389d0af418ccd844e44cf68d 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -5,6 +5,8 @@ module API
     # Prevents returning plain/text responses for files with .txt extension
     after_validation { content_type "application/json" }
 
+    helpers ::API::Helpers::HeadersHelpers
+
     helpers do
       def commit_params(attrs)
         {
@@ -40,6 +42,20 @@ module API
         }
       end
 
+      def blob_data
+        {
+          file_name: @blob.name,
+          file_path: @blob.path,
+          size: @blob.size,
+          encoding: "base64",
+          content_sha256: Digest::SHA256.hexdigest(@blob.data),
+          ref: params[:ref],
+          blob_id: @blob.id,
+          commit_id: @commit.id,
+          last_commit_id: @repo.last_commit_id_for_path(@commit.sha, params[:file_path])
+        }
+      end
+
       params :simple_file_params do
         requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
         requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.'
@@ -61,6 +77,17 @@ module API
       requires :id, type: String, desc: 'The project ID'
     end
     resource :projects, requirements: FILE_ENDPOINT_REQUIREMENTS do
+      desc 'Get raw file metadata from repository'
+      params do
+        requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
+        requires :ref, type: String, desc: 'The name of branch, tag or commit'
+      end
+      head ":id/repository/files/:file_path/raw", requirements: FILE_ENDPOINT_REQUIREMENTS do
+        assign_file_vars!
+
+        set_http_headers(blob_data)
+      end
+
       desc 'Get raw file contents from the repository'
       params do
         requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
@@ -69,9 +96,22 @@ module API
       get ":id/repository/files/:file_path/raw", requirements: FILE_ENDPOINT_REQUIREMENTS do
         assign_file_vars!
 
+        set_http_headers(blob_data)
+
         send_git_blob @repo, @blob
       end
 
+      desc 'Get file metadata from repository'
+      params do
+        requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
+        requires :ref, type: String, desc: 'The name of branch, tag or commit'
+      end
+      head ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do
+        assign_file_vars!
+
+        set_http_headers(blob_data)
+      end
+
       desc 'Get a file from the repository'
       params do
         requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
@@ -80,17 +120,11 @@ module API
       get ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do
         assign_file_vars!
 
-        {
-          file_name: @blob.name,
-          file_path: @blob.path,
-          size: @blob.size,
-          encoding: "base64",
-          content: Base64.strict_encode64(@blob.data),
-          ref: params[:ref],
-          blob_id: @blob.id,
-          commit_id: @commit.id,
-          last_commit_id: @repo.last_commit_id_for_path(@commit.sha, params[:file_path])
-        }
+        data = blob_data
+
+        set_http_headers(data)
+
+        data.merge(content: Base64.strict_encode64(@blob.data))
       end
 
       desc 'Create new file in repository'
diff --git a/lib/api/helpers/headers_helpers.rb b/lib/api/helpers/headers_helpers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cde51fccc62a4ef33f5d1ef6d481659863af20b0
--- /dev/null
+++ b/lib/api/helpers/headers_helpers.rb
@@ -0,0 +1,11 @@
+module API
+  module Helpers
+    module HeadersHelpers
+      def set_http_headers(header_data)
+        header_data.each do |key, value|
+          header "X-Gitlab-#{key.to_s.split('_').collect(&:capitalize).join('-')}", value
+        end
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index d8fdfd6dee1ae2c5793ffc9b9aeb7a9c2d5a7d9b..4bc5d3ee899b9dbad453666527b9352d7d719727 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -21,6 +21,89 @@ describe API::Files do
     "/projects/#{project.id}/repository/files/#{file_path}"
   end
 
+  describe "HEAD /projects/:id/repository/files/:file_path" do
+    shared_examples_for 'repository files' do
+      it 'returns file attributes in headers' do
+        head api(route(file_path), current_user), params
+
+        expect(response).to have_gitlab_http_status(200)
+        expect(response.headers['X-Gitlab-File-Path']).to eq(CGI.unescape(file_path))
+        expect(response.headers['X-Gitlab-File-Name']).to eq('popen.rb')
+        expect(response.headers['X-Gitlab-Last-Commit-Id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+        expect(response.headers['X-Gitlab-Content-Sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
+      end
+
+      it 'returns file by commit sha' do
+        # This file is deleted on HEAD
+        file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
+        params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"
+
+        head api(route(file_path), current_user), params
+
+        expect(response).to have_gitlab_http_status(200)
+        expect(response.headers['X-Gitlab-File-Name']).to eq('commit.js.coffee')
+        expect(response.headers['X-Gitlab-Content-Sha256']).to eq('08785f04375b47f81f46e68cc125d5ef368aa20576ddb53f91f4d83f1d04b929')
+      end
+
+      context 'when mandatory params are not given' do
+        it "responds with a 400 status" do
+          head api(route("any%2Ffile"), current_user)
+
+          expect(response).to have_gitlab_http_status(400)
+        end
+      end
+
+      context 'when file_path does not exist' do
+        it "responds with a 404 status" do
+          params[:ref] = 'master'
+
+          head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params
+
+          expect(response).to have_gitlab_http_status(404)
+        end
+      end
+
+      context 'when file_path does not exist' do
+        include_context 'disabled repository'
+
+        it "responds with a 403 status" do
+          head api(route(file_path), current_user), params
+
+          expect(response).to have_gitlab_http_status(403)
+        end
+      end
+    end
+
+    context 'when unauthenticated', 'and project is public' do
+      it_behaves_like 'repository files' do
+        let(:project) { create(:project, :public, :repository) }
+        let(:current_user) { nil }
+      end
+    end
+
+    context 'when unauthenticated', 'and project is private' do
+      it "responds with a 404 status" do
+        current_user = nil
+
+        head api(route(file_path), current_user), params
+
+        expect(response).to have_gitlab_http_status(404)
+      end
+    end
+
+    context 'when authenticated', 'as a developer' do
+      it_behaves_like 'repository files' do
+        let(:current_user) { user }
+      end
+    end
+
+    context 'when authenticated', 'as a guest' do
+      it_behaves_like '403 response' do
+        let(:request) { head api(route(file_path), guest), params }
+      end
+    end
+  end
+
   describe "GET /projects/:id/repository/files/:file_path" do
     shared_examples_for 'repository files' do
       it 'returns file attributes as json' do
@@ -30,6 +113,7 @@ describe API::Files do
         expect(json_response['file_path']).to eq(CGI.unescape(file_path))
         expect(json_response['file_name']).to eq('popen.rb')
         expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+        expect(json_response['content_sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
         expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
       end
 
@@ -51,6 +135,7 @@ describe API::Files do
 
         expect(response).to have_gitlab_http_status(200)
         expect(json_response['file_name']).to eq('commit.js.coffee')
+        expect(json_response['content_sha256']).to eq('08785f04375b47f81f46e68cc125d5ef368aa20576ddb53f91f4d83f1d04b929')
         expect(Base64.decode64(json_response['content']).lines.first).to eq("class Commit\n")
       end