Upload Files and Store URLs in Google Sheets: Automated

April 11, 2026 · 7 min read

You want a simple spreadsheet where each row has a file name, a timestamp, and a public URL that anyone can click to download or view the file. One sheet tracks every asset your team needs. Clients, invoices, design files, reports: all catalogued in Google Sheets with live links.

The problem is that Google Sheets cannot host files. It is a spreadsheet, not a storage service. You can type a URL into a cell, but Sheets will not upload, store, or serve a file for you. Most people discover this when they try to build a simple file tracking system and realize there is no "upload file and get a URL" feature anywhere in Sheets.

This guide shows you how to upload files to a hosting API and automatically write the returned URLs into Google Sheets. Three methods: Google Apps Script (free, code-based), Zapier (no-code), and Make (no-code). Each one gives you a spreadsheet that fills itself with permanent CDN links as files come in.

Why Google Sheets Cannot Host Files

Google Sheets stores data in cells: text, numbers, dates, and formulas. It has no file storage layer. When people try to work around this, they usually hit one of these walls:

What you actually want is a file hosting service that accepts a file and returns a permanent, public URL in a single API call. Then you write that URL to Sheets. The spreadsheet stays a spreadsheet. The file hosting stays separate. Each tool does what it is good at.

The Solution: FilePost + Google Sheets

FilePost is a file upload API that does exactly one thing well: you POST a file, you get a permanent CDN URL back. The file is stored on cloud infrastructure and served through a global CDN. The URL works forever, no sharing settings, no permission prompts, no preview pages.

Here is what a FilePost upload looks like:

curl -X POST https://filepost.dev/v1/upload \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@photo.jpg"

Response:

{
  "url": "https://cdn.filepost.dev/abc123/photo.jpg",
  "file_id": "abc123",
  "name": "photo.jpg",
  "size": 45321
}

That url value is what goes into your Google Sheet. The workflow is: file arrives, FilePost hosts it, the URL gets written to a new row. You end up with a spreadsheet that looks like this:

File Name URL Size Date Added
photo.jpg https://cdn.filepost.dev/abc123/photo.jpg 45 KB 2026-04-11
invoice-march.pdf https://cdn.filepost.dev/def456/invoice-march.pdf 128 KB 2026-04-11
logo-final.png https://cdn.filepost.dev/ghi789/logo-final.png 210 KB 2026-04-11

Every URL is a direct link to the file on a CDN. No authentication required for viewers. Now let's build this with each method.

Method 1: Google Apps Script

This is the most flexible method and it is completely free. Google Apps Script runs JavaScript inside Google Sheets and has built-in access to the Sheets API and HTTP requests via UrlFetchApp. You write a script once, and it runs inside your spreadsheet.

Step 1: Open the Script Editor

In your Google Sheet, go to Extensions > Apps Script. This opens the script editor. Delete any code in the default Code.gs file and paste the following script.

Step 2: Add the Upload Script

var FILEPOST_API_KEY = "YOUR_API_KEY";
var FILEPOST_UPLOAD_URL = "https://filepost.dev/v1/upload";

/**
 * Upload a file from a URL (e.g. Google Forms file upload field)
 * and append the result to the active sheet.
 */
function uploadFileAndLog(fileUrl, originalFilename) {
  // Download the file content
  var fileBlob = UrlFetchApp.fetch(fileUrl).getBlob();
  if (originalFilename) {
    fileBlob.setName(originalFilename);
  }

  // Upload to FilePost
  var options = {
    method: "post",
    headers: {
      "X-API-Key": FILEPOST_API_KEY
    },
    payload: {
      file: fileBlob
    },
    muteHttpExceptions: true
  };

  var response = UrlFetchApp.fetch(FILEPOST_UPLOAD_URL, options);
  var result = JSON.parse(response.getContentText());

  if (result.url) {
    // Append a new row: File Name, URL, Size, Timestamp
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    sheet.appendRow([
      result.name || originalFilename,
      result.url,
      result.size,
      new Date()
    ]);
    return result.url;
  } else {
    Logger.log("Upload failed: " + response.getContentText());
    return null;
  }
}

/**
 * Process new Google Form responses that include file uploads.
 * Set this as a trigger on form submit.
 */
function onFormSubmit(e) {
  var responses = e.response.getItemResponses();

  responses.forEach(function(itemResponse) {
    var fileUploads = itemResponse.getItem().getType();
    if (fileUploads == FormApp.ItemType.FILE_UPLOAD) {
      var fileIds = itemResponse.getResponse();
      fileIds.forEach(function(fileId) {
        var file = DriveApp.getFileById(fileId);
        var fileUrl = file.getDownloadUrl();
        uploadFileAndLog(fileUrl, file.getName());
      });
    }
  });
}

/**
 * Manual upload: pass a public file URL and filename.
 * Useful for testing or one-off uploads.
 */
function testUpload() {
  var url = uploadFileAndLog(
    "https://example.com/sample.pdf",
    "sample.pdf"
  );
  Logger.log("Uploaded: " + url);
}

Step 3: Set Your API Key

Replace YOUR_API_KEY at the top of the script with your actual FilePost API key. If you do not have one, sign up at filepost.dev, the free plan gives you 30 uploads per month.

Step 4: Add Column Headers

In your Google Sheet, add headers to row 1: File Name, URL, Size, Date Added. The script appends rows below these headers every time a file is uploaded.

Step 5: Set Up a Trigger (Optional)

To make this fully automatic, attach the onFormSubmit function to a Google Forms trigger. In the Apps Script editor, go to Triggers (clock icon in the left sidebar), click Add Trigger, select onFormSubmit, set the event source to From spreadsheet and event type to On form submit. Now every form submission with a file upload automatically uploads to FilePost and logs the URL.

You can also call uploadFileAndLog() from other scripts, custom menus, or time-based triggers. Since it is just a function, you can integrate it into any Apps Script workflow.

Method 2: Zapier Workflow

If you prefer no-code, Zapier can connect a form submission (or any file trigger) to FilePost and then to Google Sheets. This is a three-step Zap.

Step 1: Trigger, New Form Submission

Choose your form tool as the trigger app. This works with Typeform, JotForm, Google Forms (via Zapier), Gravity Forms, or any tool that provides a file URL on submission. Set the trigger event to New Submission or New Entry and connect your account.

When you test the trigger, you should see the file upload field containing a URL or file reference from the form tool.

Step 2: Action, Upload to FilePost

Add a Webhooks by Zapier action with the Custom Request event. Configure the request:

If your trigger provides a file URL (not raw binary), you may need an intermediate step to download the file first using a GET request via Webhooks by Zapier. Test the step to confirm you get a response with a url field.

Step 3: Action, Append Row to Google Sheets

Add a Google Sheets action with the event Create Spreadsheet Row. Select your spreadsheet and worksheet, then map the columns:

Turn on the Zap. Every form submission with a file now uploads to FilePost and logs the permanent URL in your Google Sheet automatically.

Method 3: Make (formerly Integromat) Workflow

Make uses a visual scenario builder with modules. The logic is the same as Zapier, but the interface is different.

Module 1: Trigger, Watch for New Form Entries

Add a form trigger module. Make has native modules for Typeform, JotForm, Google Forms, and dozens of other form tools. Select Watch New Responses or the equivalent for your form app. Run it once to load sample data.

Module 2: HTTP, Upload File to FilePost

Add an HTTP > Make a Request module. Configure it:

If the trigger only provides a URL (not the file blob), add a HTTP > Get a File module between the trigger and the upload module to download the file first.

Module 3: Google Sheets, Add a Row

Add a Google Sheets > Add a Row module. Connect your Google account, select the spreadsheet and sheet, then map:

Activate the scenario. Make runs it on a schedule (every 15 minutes on the free plan, or immediately on paid plans). Each new form submission flows through the pipeline: form to FilePost to Google Sheets.

Start Logging File URLs to Sheets

Upload files via API and get permanent CDN URLs. Free plan includes 30 uploads/month. Works with Apps Script, Zapier, and Make.

Get Your API Key

Example: Client File Intake to Spreadsheet

Here is a real scenario. You run an agency that collects files from clients: brand assets, documents, contracts, images. You need a shared spreadsheet where anyone on the team can see what was submitted, when, and grab the file with one click.

The setup:

  1. Create a Google Form with fields for client name, project name, and a file upload field.
  2. Link the form to a Google Sheet (Forms does this by default).
  3. Add the Apps Script from Method 1 to that sheet, or set up a Zapier/Make workflow.
  4. When a client submits the form, the file gets uploaded to FilePost. The CDN URL is written to the sheet alongside the client name and project name.

The result is a live spreadsheet your team can filter by client or project. Every file URL is a direct CDN link. No Drive permissions to manage. No "request access" popups. A team member in any country clicks the link and gets the file instantly from the nearest CDN edge.

This also solves the version problem. If a client resubmits an updated file, it gets a new row with a new URL. You have a complete history of every file submission with timestamps. The old URLs still work. Nothing gets overwritten.

Example: Automated Report Storage

Another common pattern: your system generates reports on a schedule (daily analytics, weekly summaries, monthly invoices). You want each report archived as a file and logged in a spreadsheet for the team to access.

The workflow:

  1. A scheduled script generates a report file (PDF, CSV, etc.).
  2. The script uploads the file to FilePost via API.
  3. The script appends a row to Google Sheets with the report name, URL, and timestamp.

Here is the Apps Script version for a time-triggered report logger:

function logGeneratedReport() {
  // Assume reportBlob is your generated file
  // (from another function, an external API, etc.)
  var reportBlob = generateMonthlyReport(); // your function

  var options = {
    method: "post",
    headers: {
      "X-API-Key": "YOUR_API_KEY"
    },
    payload: {
      file: reportBlob
    },
    muteHttpExceptions: true
  };

  var response = UrlFetchApp.fetch(
    "https://filepost.dev/v1/upload", options
  );
  var result = JSON.parse(response.getContentText());

  if (result.url) {
    var sheet = SpreadsheetApp.openById("YOUR_SHEET_ID")
      .getSheetByName("Reports");
    sheet.appendRow([
      result.name,
      result.url,
      result.size,
      new Date(),
      "auto-generated"
    ]);
  }
}

Set a time-based trigger (daily, weekly, monthly) in the Apps Script triggers panel. The spreadsheet becomes a living archive of every report your system has ever generated, each with a clickable CDN link.

If you use Python or Node.js for report generation instead of Apps Script, the same logic applies. Upload the file to FilePost using your language's HTTP client, then use the Google Sheets API to append the row. The FilePost upload is a single POST request in any language.

Tips for Production Workflows

Error Handling

In Apps Script, wrap the upload call in a try-catch block and log failures to a separate sheet or send yourself an email notification. In Zapier and Make, enable error notifications so you know if a step fails. FilePost returns standard HTTP status codes: 200 for success, 401 for bad API key, 413 for oversized files, 429 for rate limits.

Choosing a FilePost Plan

Think about how many files you process per month:

Plan Price Uploads/Month Max File Size
Free $0 30 50MB
Starter $9/mo 5,000 200MB
Pro $29/mo 25,000 500MB

If you are processing a handful of client submissions per week, the free plan covers it. For teams handling dozens of form submissions daily, the Starter plan provides plenty of headroom. All paid plans include unlimited storage, unlimited bandwidth, and CDN delivery.

Keeping Your API Key Secure

In Google Apps Script, store your API key using the Properties Service instead of hardcoding it. Go to Project Settings > Script Properties and add a property called FILEPOST_API_KEY. Then in your code, replace the hardcoded key with PropertiesService.getScriptProperties().getProperty("FILEPOST_API_KEY"). In Zapier and Make, API keys are stored in your account's credential vault and are not visible to shared Zap or scenario collaborators.

FAQ

Can I upload files directly to Google Sheets?

No. Google Sheets is a spreadsheet application, not a file storage service. It can only store text, numbers, and formulas in cells. To get file URLs into a spreadsheet, you need an external file hosting service like FilePost. Upload the file to FilePost via API, then write the returned CDN URL into a Google Sheets cell using Apps Script or an automation tool like Zapier or Make.

How do I store file URLs in Google Sheets automatically?

Use a file upload API like FilePost combined with an automation layer. Option 1: Write a Google Apps Script that uploads files to FilePost using UrlFetchApp and appends the returned URL to your spreadsheet. Option 2: Build a Zapier or Make workflow that triggers on a form submission or file event, uploads the file to FilePost, and appends the URL to a Google Sheets row automatically.

Does Google Sheets support file hosting?

No. Google Sheets does not host files or generate public URLs for uploaded content. Google Drive can store files, but Drive URLs require sharing permissions and are not direct CDN links. For public, permanent file URLs that you can store in a spreadsheet, use a dedicated file hosting API like FilePost, which returns a direct CDN URL for every uploaded file.

How do I use FilePost with Google Sheets?

Upload a file to FilePost using the API (POST to https://filepost.dev/v1/upload with your API key), then write the returned URL to Google Sheets. You can do this with Google Apps Script using UrlFetchApp, with Zapier using the Webhooks action followed by a Google Sheets append row action, or with Make using an HTTP module followed by a Google Sheets module. The FilePost API returns a permanent CDN URL that you store in any cell or column.

Try FilePost Free

30 free uploads per month, permanent CDN URLs, full API access. No credit card required.

Get Your Free API Key