diff --git a/components/fileforge/actions/generate-pdf/generate-pdf.mjs b/components/fileforge/actions/generate-pdf/generate-pdf.mjs
new file mode 100644
index 0000000000000..9294fc2d2798a
--- /dev/null
+++ b/components/fileforge/actions/generate-pdf/generate-pdf.mjs
@@ -0,0 +1,88 @@
+import FormData from "form-data";
+import fs from "fs";
+import {
+  checkTmp,
+  parseObject,
+} from "../../common/utils.mjs";
+import fileforge from "../../fileforge.app.mjs";
+
+export default {
+  key: "fileforge-generate-pdf",
+  name: "Generate PDF",
+  description: "Generate a PDF from provided HTML. [See the documentation](https://docs.fileforge.com/api-reference/api-reference/pdf/generate)",
+  version: "0.0.1",
+  type: "action",
+  props: {
+    fileforge,
+    alert: {
+      type: "alert",
+      alertType: "warning",
+      content: `An **\`index.html\`** file is required, and will be used as the main document.
+      Other documents may also be attached, such as stylesheets or images.
+      The path in the **\`filename\`** part of the multipart attachement will be respected during generation.
+      **Important notice:** during generation, the **\`index.html\`** file will be processed to include the base URL of the document.
+      This is required for assets to be loaded correctly.
+      To link your assets from the HTML file, you should not use a leading slash in the URL.
+      For example, use **\` \`** instead of **\`
\`** instead of **\` \`**.`,
+    },
+    files: {
+      type: "string[]",
+      label: "HTML Files",
+      description: "The HTML files to convert to PDF. Each file should be a valid path to an HTML file saved to the `/tmp` directory (e.g. `/tmp/image.png`). [See the documentation](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory)..",
+    },
+    test: {
+      type: "boolean",
+      label: "Test",
+      description: "Generate a test document instead of a production document. The generated document will contain a watermark. Defaults to true.",
+      optional: true,
+    },
+    expiresAt: {
+      type: "string",
+      label: "Expires At",
+      description: "The expiration timestamp for the PDF in ISO 8601 format",
+      optional: true,
+    },
+    fileName: {
+      type: "string",
+      label: "Filename",
+      description: "The desired filename for the generated PDF.",
+      optional: true,
+    },
+    allowViewing: {
+      type: "boolean",
+      label: "Allow Viewing",
+      description: "Specifies whether viewing is allowed.",
+      optional: true,
+    },
+  },
+  async run({ $ }) {
+    const {
+      fileforge,
+      files,
+      ...data
+    } = this;
+
+    const formData = new FormData();
+    const parsedFiles = parseObject(files);
+
+    for (const file of parsedFiles) {
+      formData.append("files", fs.createReadStream(checkTmp(file)));
+    }
+
+    formData.append("options", JSON.stringify({
+      ...data,
+      host: true,
+    }), {
+      contentType: "application/json",
+    });
+
+    const response = await fileforge.generatePDF({
+      $,
+      data: formData,
+      headers: formData.getHeaders(),
+    });
+
+    $.export("$summary", "Successfully generated the PDF file.");
+    return response;
+  },
+};
diff --git a/components/fileforge/common/utils.mjs b/components/fileforge/common/utils.mjs
new file mode 100644
index 0000000000000..d1e7ed1a22d98
--- /dev/null
+++ b/components/fileforge/common/utils.mjs
@@ -0,0 +1,31 @@
+export const parseObject = (obj) => {
+  if (!obj) return undefined;
+
+  if (Array.isArray(obj)) {
+    return obj.map((item) => {
+      if (typeof item === "string") {
+        try {
+          return JSON.parse(item);
+        } catch (e) {
+          return item;
+        }
+      }
+      return item;
+    });
+  }
+  if (typeof obj === "string") {
+    try {
+      return JSON.parse(obj);
+    } catch (e) {
+      return obj;
+    }
+  }
+  return obj;
+};
+
+export const checkTmp = (filename) => {
+  if (!filename.startsWith("/tmp")) {
+    return `/tmp/${filename}`;
+  }
+  return filename;
+};
diff --git a/components/fileforge/fileforge.app.mjs b/components/fileforge/fileforge.app.mjs
index 38d6b79e3716f..85ec8b5e6ae3b 100644
--- a/components/fileforge/fileforge.app.mjs
+++ b/components/fileforge/fileforge.app.mjs
@@ -1,11 +1,33 @@
+import { axios } from "@pipedream/platform";
+
 export default {
   type: "app",
   app: "fileforge",
-  propDefinitions: {},
   methods: {
-    // this.$auth contains connected account data
-    authKeys() {
-      console.log(Object.keys(this.$auth));
+    _baseUrl() {
+      return "https://api.fileforge.com";
+    },
+    _headers(headers = {}) {
+      return {
+        "X-API-Key": this.$auth.api_key,
+        ...headers,
+      };
+    },
+    _makeRequest({
+      $ = this, path, headers, ...opts
+    }) {
+      return axios($, {
+        url: this._baseUrl() + path,
+        headers: this._headers(headers),
+        ...opts,
+      });
+    },
+    generatePDF(opts = {}) {
+      return this._makeRequest({
+        method: "POST",
+        path: "/pdf/generate/",
+        ...opts,
+      });
     },
   },
-};
\ No newline at end of file
+};
diff --git a/components/fileforge/package.json b/components/fileforge/package.json
index 01eb9ae448875..da73c8d49d8c2 100644
--- a/components/fileforge/package.json
+++ b/components/fileforge/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@pipedream/fileforge",
-  "version": "0.0.1",
+  "version": "0.1.0",
   "description": "Pipedream Fileforge Components",
   "main": "fileforge.app.mjs",
   "keywords": [
@@ -11,5 +11,9 @@
   "author": "Pipedream  (https://pipedream.com/)",
   "publishConfig": {
     "access": "public"
+  },
+  "dependencies": {
+    "@pipedream/platform": "^3.0.1",
+    "form-data": "^4.0.0"
   }
-}
\ No newline at end of file
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1c52d6a354952..0a464fe8643ca 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3247,7 +3247,12 @@ importers:
     specifiers: {}
 
   components/fileforge:
-    specifiers: {}
+    specifiers:
+      '@pipedream/platform': ^3.0.1
+      form-data: ^4.0.0
+    dependencies:
+      '@pipedream/platform': 3.0.3
+      form-data: 4.0.0
 
   components/filestack:
     specifiers:
\`**.`,
+    },
+    files: {
+      type: "string[]",
+      label: "HTML Files",
+      description: "The HTML files to convert to PDF. Each file should be a valid path to an HTML file saved to the `/tmp` directory (e.g. `/tmp/image.png`). [See the documentation](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory)..",
+    },
+    test: {
+      type: "boolean",
+      label: "Test",
+      description: "Generate a test document instead of a production document. The generated document will contain a watermark. Defaults to true.",
+      optional: true,
+    },
+    expiresAt: {
+      type: "string",
+      label: "Expires At",
+      description: "The expiration timestamp for the PDF in ISO 8601 format",
+      optional: true,
+    },
+    fileName: {
+      type: "string",
+      label: "Filename",
+      description: "The desired filename for the generated PDF.",
+      optional: true,
+    },
+    allowViewing: {
+      type: "boolean",
+      label: "Allow Viewing",
+      description: "Specifies whether viewing is allowed.",
+      optional: true,
+    },
+  },
+  async run({ $ }) {
+    const {
+      fileforge,
+      files,
+      ...data
+    } = this;
+
+    const formData = new FormData();
+    const parsedFiles = parseObject(files);
+
+    for (const file of parsedFiles) {
+      formData.append("files", fs.createReadStream(checkTmp(file)));
+    }
+
+    formData.append("options", JSON.stringify({
+      ...data,
+      host: true,
+    }), {
+      contentType: "application/json",
+    });
+
+    const response = await fileforge.generatePDF({
+      $,
+      data: formData,
+      headers: formData.getHeaders(),
+    });
+
+    $.export("$summary", "Successfully generated the PDF file.");
+    return response;
+  },
+};
diff --git a/components/fileforge/common/utils.mjs b/components/fileforge/common/utils.mjs
new file mode 100644
index 0000000000000..d1e7ed1a22d98
--- /dev/null
+++ b/components/fileforge/common/utils.mjs
@@ -0,0 +1,31 @@
+export const parseObject = (obj) => {
+  if (!obj) return undefined;
+
+  if (Array.isArray(obj)) {
+    return obj.map((item) => {
+      if (typeof item === "string") {
+        try {
+          return JSON.parse(item);
+        } catch (e) {
+          return item;
+        }
+      }
+      return item;
+    });
+  }
+  if (typeof obj === "string") {
+    try {
+      return JSON.parse(obj);
+    } catch (e) {
+      return obj;
+    }
+  }
+  return obj;
+};
+
+export const checkTmp = (filename) => {
+  if (!filename.startsWith("/tmp")) {
+    return `/tmp/${filename}`;
+  }
+  return filename;
+};
diff --git a/components/fileforge/fileforge.app.mjs b/components/fileforge/fileforge.app.mjs
index 38d6b79e3716f..85ec8b5e6ae3b 100644
--- a/components/fileforge/fileforge.app.mjs
+++ b/components/fileforge/fileforge.app.mjs
@@ -1,11 +1,33 @@
+import { axios } from "@pipedream/platform";
+
 export default {
   type: "app",
   app: "fileforge",
-  propDefinitions: {},
   methods: {
-    // this.$auth contains connected account data
-    authKeys() {
-      console.log(Object.keys(this.$auth));
+    _baseUrl() {
+      return "https://api.fileforge.com";
+    },
+    _headers(headers = {}) {
+      return {
+        "X-API-Key": this.$auth.api_key,
+        ...headers,
+      };
+    },
+    _makeRequest({
+      $ = this, path, headers, ...opts
+    }) {
+      return axios($, {
+        url: this._baseUrl() + path,
+        headers: this._headers(headers),
+        ...opts,
+      });
+    },
+    generatePDF(opts = {}) {
+      return this._makeRequest({
+        method: "POST",
+        path: "/pdf/generate/",
+        ...opts,
+      });
     },
   },
-};
\ No newline at end of file
+};
diff --git a/components/fileforge/package.json b/components/fileforge/package.json
index 01eb9ae448875..da73c8d49d8c2 100644
--- a/components/fileforge/package.json
+++ b/components/fileforge/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@pipedream/fileforge",
-  "version": "0.0.1",
+  "version": "0.1.0",
   "description": "Pipedream Fileforge Components",
   "main": "fileforge.app.mjs",
   "keywords": [
@@ -11,5 +11,9 @@
   "author": "Pipedream  (https://pipedream.com/)",
   "publishConfig": {
     "access": "public"
+  },
+  "dependencies": {
+    "@pipedream/platform": "^3.0.1",
+    "form-data": "^4.0.0"
   }
-}
\ No newline at end of file
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1c52d6a354952..0a464fe8643ca 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3247,7 +3247,12 @@ importers:
     specifiers: {}
 
   components/fileforge:
-    specifiers: {}
+    specifiers:
+      '@pipedream/platform': ^3.0.1
+      form-data: ^4.0.0
+    dependencies:
+      '@pipedream/platform': 3.0.3
+      form-data: 4.0.0
 
   components/filestack:
     specifiers: