diff --git a/pages/redux-api-poc.tsx b/pages/redux-api-poc.tsx
index 86f369323bd601379d1765822b11e9fd54d178b1..f6add11e9d67d6f2fa1d73b3f6f89ac7a1ed6da2 100644
--- a/pages/redux-api-poc.tsx
+++ b/pages/redux-api-poc.tsx
@@ -1,4 +1,5 @@
 import { getBioEntityContents } from '@/redux/bioEntityContents/bioEntityContents.thunks';
+import { getChemicals } from '@/redux/chemicals/chemicals.thunks';
 import { getDrugs } from '@/redux/drugs/drugs.thunks';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { getMirnas } from '@/redux/mirnas/mirnas.thunks';
@@ -17,6 +18,7 @@ const ReduxPage = (): JSX.Element => {
     dispatch(getDrugs('aspirin'));
     dispatch(getMirnas('hsa-miR-302b-3p'));
     dispatch(getBioEntityContents('park7'));
+    dispatch(getChemicals('Corticosterone'));
   };
 
   return (
diff --git a/src/models/chemicalSchema.ts b/src/models/chemicalSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eafa7c257b1ce8886772745f73f147043d0a9573
--- /dev/null
+++ b/src/models/chemicalSchema.ts
@@ -0,0 +1,15 @@
+import { idSchema } from '@/models/idSchema';
+import { z } from 'zod';
+import { referenceSchema } from './referenceSchema';
+import { targetSchema } from './targetSchema';
+
+export const chemicalSchema = z.object({
+  id: idSchema,
+  name: z.string(),
+  description: z.string(),
+  directEvidence: z.string().nullable(),
+  directEvidenceReferences: z.array(referenceSchema),
+  synonyms: z.array(z.string()),
+  references: z.array(referenceSchema),
+  targets: z.array(targetSchema),
+});
diff --git a/src/models/fixtures/chemicalsFixture.ts b/src/models/fixtures/chemicalsFixture.ts
new file mode 100644
index 0000000000000000000000000000000000000000..88e2169170f74600809a1329280c1f9549527e20
--- /dev/null
+++ b/src/models/fixtures/chemicalsFixture.ts
@@ -0,0 +1,10 @@
+import { ZOD_SEED } from '@/constants';
+import { chemicalSchema } from '@/models/chemicalSchema';
+import { z } from 'zod';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { createFixture } from 'zod-fixture';
+
+export const chemicalsFixture = createFixture(z.array(chemicalSchema), {
+  seed: ZOD_SEED,
+  array: { min: 2, max: 2 },
+});
diff --git a/src/models/idSchema.ts b/src/models/idSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2ccc4d780bd3185097e86bdac53ec45abd1c848b
--- /dev/null
+++ b/src/models/idSchema.ts
@@ -0,0 +1,9 @@
+import { z } from 'zod';
+
+export const idSchema = z.object({
+  annotatorClassName: z.string(),
+  id: z.number(),
+  link: z.string(),
+  resource: z.string(),
+  type: z.string(),
+});
diff --git a/src/redux/apiPath.test.ts b/src/redux/apiPath.test.ts
index ca36caaedbba792346899f05ee6bb45010727e3d..e1337f97c6f7f73f141d5739313c1868ab357f30 100644
--- a/src/redux/apiPath.test.ts
+++ b/src/redux/apiPath.test.ts
@@ -19,4 +19,10 @@ describe('api path', () => {
       `projects/${PROJECT_ID}/models/*/bioEntities:search?query=park7`,
     );
   });
+
+  it('should return url string for bio entity content', () => {
+    expect(apiPath.getChemicalsStringWithQuery('Corticosterone')).toBe(
+      `projects/${PROJECT_ID}/chemicals:search?query=Corticosterone`,
+    );
+  });
 });
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index d199de1ecbe4405c0af4b766000fff2fb5b84e7f..8469a3d16b0f7eb0e9144339ff69da900564e86c 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -7,4 +7,6 @@ export const apiPath = {
     `projects/${PROJECT_ID}/drugs:search?query=${searchQuery}`,
   getMirnasStringWithQuery: (searchQuery: string): string =>
     `projects/${PROJECT_ID}/miRnas:search?query=${searchQuery}`,
+  getChemicalsStringWithQuery: (searchQuery: string): string =>
+    `projects/${PROJECT_ID}/chemicals:search?query=${searchQuery}`,
 };
diff --git a/src/redux/chemicals/chemicals.reducers.test.ts b/src/redux/chemicals/chemicals.reducers.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e74d817181ca064e3b36069fcb3ffc398dfce54a
--- /dev/null
+++ b/src/redux/chemicals/chemicals.reducers.test.ts
@@ -0,0 +1,79 @@
+import { chemicalsFixture } from '@/models/fixtures/chemicalsFixture';
+import { apiPath } from '@/redux/apiPath';
+import {
+  ToolkitStoreWithSingleSlice,
+  createStoreInstanceUsingSliceReducer,
+} from '@/utils/createStoreInstanceUsingSliceReducer';
+import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
+import { HttpStatusCode } from 'axios';
+import chemicalsReducer from './chemicals.slice';
+import { getChemicals } from './chemicals.thunks';
+import { ChemicalsState } from './chemicals.types';
+
+const mockedAxiosClient = mockNetworkResponse();
+const SEARCH_QUERY = 'Corticosterone';
+
+const INITIAL_STATE: ChemicalsState = {
+  data: [],
+  loading: 'idle',
+  error: { name: '', message: '' },
+};
+
+describe('chemicals reducer', () => {
+  let store = {} as ToolkitStoreWithSingleSlice<ChemicalsState>;
+  beforeEach(() => {
+    store = createStoreInstanceUsingSliceReducer('chemicals', chemicalsReducer);
+  });
+
+  it('should match initial state', () => {
+    const action = { type: 'unknown' };
+
+    expect(chemicalsReducer(undefined, action)).toEqual(INITIAL_STATE);
+  });
+  it('should update store after succesfull getChemicals query', async () => {
+    mockedAxiosClient
+      .onGet(apiPath.getChemicalsStringWithQuery(SEARCH_QUERY))
+      .reply(HttpStatusCode.Ok, chemicalsFixture);
+
+    const { type } = await store.dispatch(getChemicals(SEARCH_QUERY));
+    const { data, loading, error } = store.getState().chemicals;
+
+    expect(type).toBe('project/getChemicals/fulfilled');
+    expect(loading).toEqual('succeeded');
+    expect(error).toEqual({ message: '', name: '' });
+    expect(data).toEqual(chemicalsFixture);
+  });
+
+  it('should update store after failed getChemicals query', async () => {
+    mockedAxiosClient
+      .onGet(apiPath.getChemicalsStringWithQuery(SEARCH_QUERY))
+      .reply(HttpStatusCode.NotFound, chemicalsFixture);
+
+    const { type } = await store.dispatch(getChemicals(SEARCH_QUERY));
+    const { data, loading, error } = store.getState().chemicals;
+
+    expect(type).toBe('project/getChemicals/rejected');
+    expect(loading).toEqual('failed');
+    expect(error).toEqual({ message: '', name: '' });
+    expect(data).toEqual([]);
+  });
+
+  it('should update store on loading getChemicals query', async () => {
+    mockedAxiosClient
+      .onGet(apiPath.getChemicalsStringWithQuery(SEARCH_QUERY))
+      .reply(HttpStatusCode.Ok, chemicalsFixture);
+
+    const chemicalsPromise = store.dispatch(getChemicals(SEARCH_QUERY));
+
+    const { data, loading } = store.getState().chemicals;
+    expect(data).toEqual([]);
+    expect(loading).toEqual('pending');
+
+    chemicalsPromise.then(() => {
+      const { data: dataPromiseFulfilled, loading: promiseFulfilled } = store.getState().chemicals;
+
+      expect(dataPromiseFulfilled).toEqual(chemicalsFixture);
+      expect(promiseFulfilled).toEqual('succeeded');
+    });
+  });
+});
diff --git a/src/redux/chemicals/chemicals.reducers.ts b/src/redux/chemicals/chemicals.reducers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ca1b96f7034944c01b3743544220faa9e563090
--- /dev/null
+++ b/src/redux/chemicals/chemicals.reducers.ts
@@ -0,0 +1,17 @@
+import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
+import { getChemicals } from './chemicals.thunks';
+import { ChemicalsState } from './chemicals.types';
+
+export const getChemicalsReducer = (builder: ActionReducerMapBuilder<ChemicalsState>): void => {
+  builder.addCase(getChemicals.pending, state => {
+    state.loading = 'pending';
+  });
+  builder.addCase(getChemicals.fulfilled, (state, action) => {
+    state.data = action.payload;
+    state.loading = 'succeeded';
+  });
+  builder.addCase(getChemicals.rejected, state => {
+    state.loading = 'failed';
+    // TODO to discuss manage state of failure
+  });
+};
diff --git a/src/redux/chemicals/chemicals.slice.ts b/src/redux/chemicals/chemicals.slice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a8dd8e593bfca43771ec553bac8face485b88a2d
--- /dev/null
+++ b/src/redux/chemicals/chemicals.slice.ts
@@ -0,0 +1,20 @@
+import { ChemicalsState } from '@/redux/chemicals/chemicals.types';
+import { createSlice } from '@reduxjs/toolkit';
+import { getChemicalsReducer } from './chemicals.reducers';
+
+const initialState: ChemicalsState = {
+  data: [],
+  loading: 'idle',
+  error: { name: '', message: '' },
+};
+
+export const chemicalsSlice = createSlice({
+  name: 'chemicals',
+  initialState,
+  reducers: {},
+  extraReducers: builder => {
+    getChemicalsReducer(builder);
+  },
+});
+
+export default chemicalsSlice.reducer;
diff --git a/src/redux/chemicals/chemicals.thunks.test.ts b/src/redux/chemicals/chemicals.thunks.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..93945477c94dd25afcf561a04ac592ce57d12f2e
--- /dev/null
+++ b/src/redux/chemicals/chemicals.thunks.test.ts
@@ -0,0 +1,39 @@
+import { chemicalsFixture } from '@/models/fixtures/chemicalsFixture';
+import { apiPath } from '@/redux/apiPath';
+import {
+  ToolkitStoreWithSingleSlice,
+  createStoreInstanceUsingSliceReducer,
+} from '@/utils/createStoreInstanceUsingSliceReducer';
+import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
+import { HttpStatusCode } from 'axios';
+import chemicalsReducer from './chemicals.slice';
+import { getChemicals } from './chemicals.thunks';
+import { ChemicalsState } from './chemicals.types';
+
+const mockedAxiosClient = mockNetworkResponse();
+const SEARCH_QUERY = 'Corticosterone';
+
+describe('chemicals thunks', () => {
+  let store = {} as ToolkitStoreWithSingleSlice<ChemicalsState>;
+  beforeEach(() => {
+    store = createStoreInstanceUsingSliceReducer('chemicals', chemicalsReducer);
+  });
+  describe('getChemiclas', () => {
+    it('should return data when data response from API is valid', async () => {
+      mockedAxiosClient
+        .onGet(apiPath.getChemicalsStringWithQuery(SEARCH_QUERY))
+        .reply(HttpStatusCode.Ok, chemicalsFixture);
+
+      const { payload } = await store.dispatch(getChemicals(SEARCH_QUERY));
+      expect(payload).toEqual(chemicalsFixture);
+    });
+    it('should return undefined when data response from API is not valid ', async () => {
+      mockedAxiosClient
+        .onGet(apiPath.getChemicalsStringWithQuery(SEARCH_QUERY))
+        .reply(HttpStatusCode.Ok, { randomProperty: 'randomValue' });
+
+      const { payload } = await store.dispatch(getChemicals(SEARCH_QUERY));
+      expect(payload).toEqual(undefined);
+    });
+  });
+});
diff --git a/src/redux/chemicals/chemicals.thunks.ts b/src/redux/chemicals/chemicals.thunks.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df0f9dec0db3cf06752fb5bcb80568990112ea32
--- /dev/null
+++ b/src/redux/chemicals/chemicals.thunks.ts
@@ -0,0 +1,20 @@
+import { chemicalSchema } from '@/models/chemicalSchema';
+import { apiPath } from '@/redux/apiPath';
+import { axiosInstance } from '@/services/api/utils/axiosInstance';
+import { Chemical } from '@/types/models';
+import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
+import { createAsyncThunk } from '@reduxjs/toolkit';
+import { z } from 'zod';
+
+export const getChemicals = createAsyncThunk(
+  'project/getChemicals',
+  async (searchQuery: string): Promise<Chemical[] | undefined> => {
+    const response = await axiosInstance.get<Chemical[]>(
+      apiPath.getChemicalsStringWithQuery(searchQuery),
+    );
+
+    const isDataValid = validateDataUsingZodSchema(response.data, z.array(chemicalSchema));
+
+    return isDataValid ? response.data : undefined;
+  },
+);
diff --git a/src/redux/chemicals/chemicals.types.ts b/src/redux/chemicals/chemicals.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..653e910ab23427b38d7a24d6c6caecc588d46af2
--- /dev/null
+++ b/src/redux/chemicals/chemicals.types.ts
@@ -0,0 +1,4 @@
+import { FetchDataState } from '@/types/fetchDataState';
+import { Chemical } from '@/types/models';
+
+export type ChemicalsState = FetchDataState<Chemical[]>;
diff --git a/src/types/models.ts b/src/types/models.ts
index 52aca9ac48e7ec7903544dacf3442d6a28ca911e..abadf02ac342719044fbc94260c65ed3704d8b71 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -1,9 +1,10 @@
+import { bioEntityContentSchema } from '@/models/bioEntityContentSchema';
+import { chemicalSchema } from '@/models/chemicalSchema';
 import { disease } from '@/models/disease';
 import { drugSchema } from '@/models/drugSchema';
+import { mirnaSchema } from '@/models/mirnaSchema';
 import { organism } from '@/models/organism';
 import { projectSchema } from '@/models/project';
-import { mirnaSchema } from '@/models/mirnaSchema';
-import { bioEntityContentSchema } from '@/models/bioEntityContentSchema';
 import { z } from 'zod';
 
 export type Project = z.infer<typeof projectSchema>;
@@ -12,3 +13,4 @@ export type Disease = z.infer<typeof disease>;
 export type Drug = z.infer<typeof drugSchema>;
 export type Mirna = z.infer<typeof mirnaSchema>;
 export type BioEntityContent = z.infer<typeof bioEntityContentSchema>;
+export type Chemical = z.infer<typeof chemicalSchema>;