diff --git a/__tests__/ai/__snapshots__/pull.test.js.snap b/__tests__/ai/__snapshots__/pull.test.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..f90daf34947ac1a9ef79403ab267da7f7ff658da
--- /dev/null
+++ b/__tests__/ai/__snapshots__/pull.test.js.snap
@@ -0,0 +1,40 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`ai pull model > given a user tries to access > should respond with a proper body 1`] = `
+{
+  "message": "Access Forbidden",
+}
+`;
+
+exports[`ai pull model > given no jwt sended > should respond with a proper body 1`] = `
+{
+  "message": "No access token found. Access denied.",
+}
+`;
+
+exports[`ai pull model > given no matching model found > should respond with a proper body 1`] = `
+{
+  "message": "pull model manifest: file does not exist",
+}
+`;
+
+exports[`ai pull model > given no valid jwt sended > should respond with a proper body 1`] = `
+{
+  "message": "Access token is no longer valid. Access denied.",
+}
+`;
+
+exports[`ai pull model > given required fields are missing > should respond with a proper body 1`] = `
+{
+  "message": "Validation errors. Please check the error messages.",
+  "validationErrors": {
+    "model": "Required",
+  },
+}
+`;
+
+exports[`ai pull model > given the inputs are valid > should respond with a proper body 1`] = `
+{
+  "status": "success",
+}
+`;
diff --git a/__tests__/ai/pull.test.js b/__tests__/ai/pull.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ef59fcf74eda454e715e363d9757caa5a75c517
--- /dev/null
+++ b/__tests__/ai/pull.test.js
@@ -0,0 +1,187 @@
+// import vitest, supertest & app
+import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest';
+import supertest from "supertest";
+import app from "../../app.js";
+import jwt from 'jsonwebtoken';
+
+// set route
+const ROUTE = '/ai/models';
+// prepare response of each test
+let response;
+
+// ############################
+//  OBJECTS
+// ############################
+const mockedVals = vi.hoisted(() => {
+  return {
+    foundUser: {
+      _id: '66a29da2942b3eb',
+      username: 'snoopy',
+      name: 'My User',
+      email: 'user@mail.local',
+      verified: true,
+      role: 4,
+      createdAt: '2024-07 - 25T18: 46: 58.982Z',
+      updatedAt: '2024-07 - 25T18: 46: 58.982Z',
+      __v: 0,
+      fullname: '',
+      id: '66a29da2942b3ebcaf047f07'
+    },
+    validInput: {
+      model: 'llama3'
+    }
+  };
+});
+
+// ############################
+//  MOCKS
+// ############################
+import * as dbService from '../../utils/handleDB.js';
+// mock dbService
+vi.mock('../../utils/handleDB.js', async (importOriginal) => {
+  return {
+    ...await importOriginal(),
+    dbConnection: vi.fn(() => 'mocked'),
+    findOneRecord: vi.fn(() => mockedVals.foundUser),
+  };
+});
+
+// import AI Service
+import * as aiService from '../../utils/handleAI.js';
+// mock aiService
+vi.mock('../../utils/handleAI.js', async (importOriginal) => {
+  return {
+    ...await importOriginal(),
+    aiInstallModel: vi.fn().mockImplementation(() => { return { status: 'success' }; }),
+  };
+});
+
+// ############################
+//  TESTS
+// ############################
+
+describe('ai pull model', () => {
+  const _jwt = (id, role) => {
+    return jwt.sign({ id, role }, process.env.JWT_SECRET_KEY, { expiresIn: process.env.JWT_TTL });
+  };
+
+  describe('given the inputs are valid', async () => {
+    beforeAll(async () => {
+      response = await supertest(app)
+        .put(ROUTE)
+        .set('Authorization', `Bearer ${_jwt(mockedVals.foundUser.id, mockedVals.foundUser.role)}`)
+        .send(mockedVals.validInput);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(200);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+
+
+  // ############################
+
+  describe('given no matching model found', () => {
+    beforeAll(async () => {
+      const input = { ...mockedVals.validInput, model: 'unknownModel' };
+
+      let error = new Error("pull model manifest: file does not exist");
+      error.name = 'ResponseError';
+      error.status = 500;
+      aiService.aiInstallModel.mockImplementation(() => { throw error; });
+
+      response = await supertest(app)
+        .put(ROUTE)
+        .set('Authorization', `Bearer ${_jwt(mockedVals.foundUser.id, mockedVals.foundUser.role)}`)
+        .send(input);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(500);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+
+  // ############################
+
+  describe('given required fields are missing', () => {
+    beforeAll(async () => {
+      const { model, ...input } = mockedVals.validInput;
+
+      response = await supertest(app)
+        .put(ROUTE)
+        .set('Authorization', `Bearer ${_jwt(mockedVals.foundUser.id, mockedVals.foundUser.role)}`)
+        .send(input);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(400);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+
+  // ############################
+
+  describe('given a user tries to access', () => {
+    beforeAll(async () => {
+
+      dbService.findOneRecord.mockImplementationOnce(async () => {
+        return { ...mockedVals.foundUser, role: 0 };
+      });
+
+      response = await supertest(app)
+        .put(ROUTE)
+        .set('Authorization', `Bearer ${_jwt(mockedVals.foundUser.id, 0)}`)
+        .send(mockedVals.validInput);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(403);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+
+  // ############################
+
+  describe('given no valid jwt sended', () => {
+    beforeAll(async () => {
+      response = await supertest(app)
+        .put(ROUTE)
+        .set('Authorization', `Bearer invalid`)
+        .send(mockedVals.validInput);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(403);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+
+  // ############################
+
+  describe('given no jwt sended', () => {
+    beforeAll(async () => {
+      response = await supertest(app)
+        .put(ROUTE)
+        .send(mockedVals.validInput);
+    });
+
+    it('should return a proper status code status', () => {
+      expect(response.status).toBe(401);
+    });
+    it('should respond with a proper body', () => {
+      expect(response.body).toMatchSnapshot();
+    });
+  });
+});
\ No newline at end of file
diff --git a/__tests__/manualREST/ollama.rest b/__tests__/manualREST/ollama.rest
index c3484fb5713daa15a99b1d134cfe36af51fb9f7e..043dd5aa89e1f8ba6d00561e7a42beec84727103 100644
--- a/__tests__/manualREST/ollama.rest
+++ b/__tests__/manualREST/ollama.rest
@@ -64,7 +64,7 @@ Content-Type: application/json
 
 ### pull a specific model
 # @name pull_model
-POST {{host}}/ai/models/pull
+PUT {{host}}/ai/models
 Authorization: Bearer {{token}}
 Accept: application/json
 Content-Type: application/json
diff --git a/logs/__tests__/ai/pull.test.js b/logs/__tests__/ai/pull.test.js
deleted file mode 100644
index 8792df059d1d885f94581b9de2695b2c63bb786d..0000000000000000000000000000000000000000
--- a/logs/__tests__/ai/pull.test.js
+++ /dev/null
@@ -1,156 +0,0 @@
-// import vitest, supertest & app
-import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest';
-import supertest from "supertest";
-import app from "../../app.js";
-// ignore expiration of the (self-signed) certificate
-process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
-// set timeout
-const BEFORE_ALL_TIMEOUT = 30000; // 30 sec
-// set route
-const ROUTE = '/ai/models/pull';
-// prepare response of each test
-let response;
-
-// ############################
-//  OBJECTS
-// ############################
-
-const noModelFoundResponse = {
-  code: 500,
-  message: "pull model manifest: file does not exist",
-  data: {}
-};
-// ############################
-//  MOCKS
-// ############################
-// import PocketBase Service
-import * as pbService from '../../utils/pocketbase/handlePocketBase.js';
-// mock pbService
-vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) => {
-  return {
-    ...await importOriginal(),
-    pbVerifyAccessToken: vi.fn().mockImplementation((req, res, next) => {
-      next();
-    }),
-    gateKeeper: vi.fn().mockImplementation((req, res, next) => {
-      return next();
-    })
-  };
-});
-
-// import AI Service
-import * as aiService from '../../utils/handleAI.js';
-// mock aiService
-vi.mock('../../utils/handleAI.js', async (importOriginal) => {
-  return {
-    ...await importOriginal(),
-    aiInstallModel: vi.fn().mockImplementation(() => { return { status: 'success' }; }),
-  };
-});
-
-// ############################
-//  TESTS
-// ############################
-
-describe('ai pull model', () => {
-  describe('given the inputs are valid', async () => {
-    response = await supertest(app)
-      .post(ROUTE)
-      .set('Authorization', 'Bearer 123valid')
-      .send({ model: 'validModelName' });
-    it('should have called the gateKeeper', () => {
-      expect(pbService.gateKeeper).toHaveBeenCalledTimes(1);
-    });
-    it('should return a proper status code', () => {
-      expect(response.status).toBe(200);
-    });
-    it('should respond with a proper message', () => {
-      expect(response.body).toEqual({ status: 'success' });
-    });
-  });
-
-  // ############################
-
-  describe('given no valid JWT sent', () => {
-    beforeAll(async () => {
-      pbService.pbVerifyAccessToken.mockImplementationOnce((req, res, next) => {
-        return res.status(403).json({ message: 'You are not logged in.' });
-      });
-
-      response = await supertest(app)
-        .post(ROUTE)
-        .send({ model: 'validModelName' });
-    }, BEFORE_ALL_TIMEOUT);
-    it('should return a proper status code', () => {
-      expect(response.status).toBe(403);
-    });
-    it('should respond with a proper message', () => {
-      expect(response.body.message).toEqual('You are not logged in.');
-    });
-  });
-
-
-  // ############################
-
-  describe('given no access granted', () => {
-    beforeAll(async () => {
-      pbService.gateKeeper.mockImplementationOnce((req, res, next) => {
-        return res.status(403).json({ message: 'Access Forbidden' });
-      });
-
-      response = await supertest(app)
-        .post(ROUTE)
-        .set('Authorization', 'Bearer 123valid');
-    }, BEFORE_ALL_TIMEOUT);
-
-    it('should return a proper status code', () => {
-      expect(response.status).toBe(403);
-    });
-    it('should respond with a proper message', () => {
-      expect(response.body.message).toEqual('Access Forbidden');
-    });
-  });
-
-  // ############################
-
-  describe('given no model name sent', () => {
-    beforeAll(async () => {
-      response = await supertest(app)
-        .post(ROUTE)
-        .set('Authorization', 'Bearer 123valid');
-    }, BEFORE_ALL_TIMEOUT);
-    it('should return a proper status code', () => {
-      expect(response.status).toBe(400);
-    });
-    it('should respond with a proper message', () => {
-      expect(response.body.validationErrors.model).toEqual('Required');
-    });
-  });
-
-  // ############################
-
-  describe('given no matching model found', () => {
-    beforeAll(async () => {
-      let error = new Error('pull model manifest: file does not exist');
-      error.name = 'ResponseError';
-      error.response = noModelFoundResponse;
-      error.status = 500;
-      aiService.aiInstallModel.mockImplementation(() => { throw error; });
-
-      response = await supertest(app)
-        .post(ROUTE)
-        .set('Authorization', 'Bearer 123valid')
-        .send({ model: 'invalidModelName' });
-    }, BEFORE_ALL_TIMEOUT);
-    it('should force aiInstallModel to throw an error', () => {
-      expect(aiService.aiInstallModel).toThrowError();
-    });
-    it('should return a proper status code', () => {
-      expect(response.status).toBe(500);
-    });
-    it('should respond with a proper message', () => {
-      expect(response.body.message).toEqual('pull model manifest: file does not exist');
-    });
-  });
-
-});
\ No newline at end of file
diff --git a/routes/ai.js b/routes/ai.js
index 105b7004bedd94c8f934b406d4636ccb25bffeda..bfbbecdd3f08044977c66acb16a97cdf66387e68 100644
--- a/routes/ai.js
+++ b/routes/ai.js
@@ -50,7 +50,7 @@ router.post('/model', verifyAccessToken, validate(getModelSchema), getModel);
  * 
  * @return  {string}         installation response
  */
-router.post('/models/pull', verifyAccessToken, gateKeeper, validate(installModelSchema), installModel);
+router.put('/models', verifyAccessToken, gateKeeper, validate(installModelSchema), installModel);
 
 
 /**