diff --git a/api/index.js b/api/index.js
index c42bc04891234..b897d57e45dd3 100644
--- a/api/index.js
+++ b/api/index.js
@@ -38,6 +38,7 @@ export default async (req, res) => {
     border_color,
     rank_icon,
     show,
+    role,
   } = req.query;
   res.setHeader("Content-Type", "image/svg+xml");
 
@@ -71,6 +72,7 @@ export default async (req, res) => {
       username,
       parseBoolean(include_all_commits),
       parseArray(exclude_repo),
+      parseArray(role),
       showStats.includes("prs_merged") ||
         showStats.includes("prs_merged_percentage"),
       showStats.includes("discussions_started"),
diff --git a/api/top-langs.js b/api/top-langs.js
index c5bed634c1eab..de594ef8a78e0 100644
--- a/api/top-langs.js
+++ b/api/top-langs.js
@@ -32,6 +32,7 @@ export default async (req, res) => {
     border_color,
     disable_animations,
     hide_progress,
+    role,
   } = req.query;
   res.setHeader("Content-Type", "image/svg+xml");
 
@@ -67,6 +68,7 @@ export default async (req, res) => {
       parseArray(exclude_repo),
       size_weight,
       count_weight,
+      parseArray(role),
     );
 
     let cacheSeconds = parseInt(
diff --git a/src/common/utils.js b/src/common/utils.js
index b780657c1c244..438e4a4c2af2d 100644
--- a/src/common/utils.js
+++ b/src/common/utils.js
@@ -6,6 +6,8 @@ import { themes } from "../../themes/index.js";
 
 const TRY_AGAIN_LATER = "Please try again later";
 
+const OWNER_AFFILIATIONS = ["OWNER", "COLLABORATOR", "ORGANIZATION_MEMBER"];
+
 const SECONDARY_ERROR_MESSAGES = {
   MAX_RETRY:
     "You can deploy own instance or wait until public will be no longer limited",
@@ -15,6 +17,9 @@ const SECONDARY_ERROR_MESSAGES = {
   GRAPHQL_ERROR: TRY_AGAIN_LATER,
   GITHUB_REST_API_ERROR: TRY_AGAIN_LATER,
   WAKATIME_USER_NOT_FOUND: "Make sure you have a public WakaTime profile",
+  INVALID_AFFILIATION: `Invalid owner affiliations. Valid values are: ${OWNER_AFFILIATIONS.join(
+    ", ",
+  )}`,
 };
 
 /**
@@ -37,6 +42,7 @@ class CustomError extends Error {
   static GRAPHQL_ERROR = "GRAPHQL_ERROR";
   static GITHUB_REST_API_ERROR = "GITHUB_REST_API_ERROR";
   static WAKATIME_ERROR = "WAKATIME_ERROR";
+  static INVALID_AFFILIATION = "INVALID_AFFILIATION";
 }
 
 /**
@@ -585,6 +591,37 @@ const parseEmojis = (str) => {
   });
 };
 
+/**
+ * Parse owner affiliations.
+ *
+ * @param {string[]} affiliations
+ * @returns {string[]} Parsed affiliations.
+ *
+ * @throws {CustomError} If affiliations contains invalid values.
+ */
+const parseOwnerAffiliations = (affiliations) => {
+  // Set default value for ownerAffiliations.
+  // NOTE: Done here since parseArray() will always return an empty array even nothing
+  //was specified.
+  affiliations =
+    affiliations && affiliations.length > 0
+      ? affiliations.map((affiliation) => affiliation.toUpperCase())
+      : ["OWNER"];
+
+  // Check if ownerAffiliations contains valid values.
+  if (
+    affiliations.some(
+      (affiliation) => !OWNER_AFFILIATIONS.includes(affiliation),
+    )
+  ) {
+    throw new CustomError(
+      "Invalid query parameter",
+      CustomError.INVALID_AFFILIATION,
+    );
+  }
+  return affiliations;
+};
+
 /**
  * Get diff in minutes between two dates.
  *
@@ -618,11 +655,13 @@ export {
   wrapTextMultiline,
   logger,
   CONSTANTS,
+  OWNER_AFFILIATIONS,
   CustomError,
   MissingParamError,
   measureText,
   lowercaseTrim,
   chunkArray,
   parseEmojis,
+  parseOwnerAffiliations,
   dateDiff,
 };
diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js
index 115cd50a51564..47f6739fa5f2b 100644
--- a/src/fetchers/stats-fetcher.js
+++ b/src/fetchers/stats-fetcher.js
@@ -10,13 +10,14 @@ import {
   MissingParamError,
   request,
   wrapTextMultiline,
+  parseOwnerAffiliations,
 } from "../common/utils.js";
 
 dotenv.config();
 
 // GraphQL queries.
 const GRAPHQL_REPOS_FIELD = `
-  repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
+  repositories(first: 100, after: $after, ownerAffiliations: $ownerAffiliations, orderBy: {direction: DESC, field: STARGAZERS}) {
     totalCount
     nodes {
       name
@@ -32,15 +33,15 @@ const GRAPHQL_REPOS_FIELD = `
 `;
 
 const GRAPHQL_REPOS_QUERY = `
-  query userInfo($login: String!, $after: String) {
-    user(login: $login) {
+  query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
+    user(login: $login, ownerAffiliations: $ownerAffiliations) {
       ${GRAPHQL_REPOS_FIELD}
     }
   }
 `;
 
 const GRAPHQL_STATS_QUERY = `
-  query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!) {
+  query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation], $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!) {
     user(login: $login) {
       name
       login
@@ -106,6 +107,7 @@ const fetcher = (variables, token) => {
  *
  * @param {object} variables Fetcher variables.
  * @param {string} variables.username Github username.
+ * @param {string[]} variables.ownerAffiliations The owner affiliations to filter by. Default: OWNER.
  * @param {boolean} variables.includeMergedPullRequests Include merged pull requests.
  * @param {boolean} variables.includeDiscussions Include discussions.
  * @param {boolean} variables.includeDiscussionsAnswers Include discussions answers.
@@ -115,6 +117,7 @@ const fetcher = (variables, token) => {
  */
 const statsFetcher = async ({
   username,
+  ownerAffiliations,
   includeMergedPullRequests,
   includeDiscussions,
   includeDiscussionsAnswers,
@@ -127,6 +130,7 @@ const statsFetcher = async ({
       login: username,
       first: 100,
       after: endCursor,
+      ownerAffiliations: ownerAffiliations,
       includeMergedPullRequests,
       includeDiscussions,
       includeDiscussionsAnswers,
@@ -214,6 +218,7 @@ const totalCommitsFetcher = async (username) => {
  * @param {string} username GitHub username.
  * @param {boolean} include_all_commits Include all commits.
  * @param {string[]} exclude_repo Repositories to exclude.
+ * @param {string[]} ownerAffiliations Owner affiliations. Default: OWNER.
  * @param {boolean} include_merged_pull_requests Include merged pull requests.
  * @param {boolean} include_discussions Include discussions.
  * @param {boolean} include_discussions_answers Include discussions answers.
@@ -223,6 +228,7 @@ const fetchStats = async (
   username,
   include_all_commits = false,
   exclude_repo = [],
+  ownerAffiliations = [],
   include_merged_pull_requests = false,
   include_discussions = false,
   include_discussions_answers = false,
@@ -245,9 +251,11 @@ const fetchStats = async (
     contributedTo: 0,
     rank: { level: "C", percentile: 100 },
   };
+  ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
 
   let res = await statsFetcher({
     username,
+    ownerAffiliations,
     includeMergedPullRequests: include_merged_pull_requests,
     includeDiscussions: include_discussions,
     includeDiscussionsAnswers: include_discussions_answers,
diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js
index 485cc8b75de8a..9809d9ce87bad 100644
--- a/src/fetchers/top-languages-fetcher.js
+++ b/src/fetchers/top-languages-fetcher.js
@@ -6,6 +6,7 @@ import {
   MissingParamError,
   request,
   wrapTextMultiline,
+  parseOwnerAffiliations,
 } from "../common/utils.js";
 
 /**
@@ -24,10 +25,10 @@ const fetcher = (variables, token) => {
   return request(
     {
       query: `
-      query userInfo($login: String!) {
+      query userInfo($login: String!, $ownerAffiliations: [RepositoryAffiliation]) {
         user(login: $login) {
-          # fetch only owner repos & not forks
-          repositories(ownerAffiliations: OWNER, isFork: false, first: 100) {
+          # do not fetch forks
+          repositories(ownerAffiliations: $ownerAffiliations, isFork: false, first: 100) {
             nodes {
               name
               languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
@@ -61,6 +62,7 @@ const fetcher = (variables, token) => {
  *
  * @param {string} username GitHub username.
  * @param {string[]} exclude_repo List of repositories to exclude.
+ * @param {string[]} ownerAffiliations The owner affiliations to filter by. Default: OWNER.
  * @param {number} size_weight Weightage to be given to size.
  * @param {number} count_weight Weightage to be given to count.
  * @returns {Promise<TopLangData>} Top languages data.
@@ -70,12 +72,14 @@ const fetchTopLanguages = async (
   exclude_repo = [],
   size_weight = 1,
   count_weight = 0,
+  ownerAffiliations = [],
 ) => {
   if (!username) {
     throw new MissingParamError(["username"]);
   }
+  ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
 
-  const res = await retryer(fetcher, { login: username });
+  const res = await retryer(fetcher, { login: username, ownerAffiliations });
 
   if (res.data.errors) {
     logger.error(res.data.errors);