<< Back to Insights

How to Upload and Download Files With a REST API

2242 words Human made

Published 2026-10-07 05:07:05.720699 by Carsten Blum


Your application needs somewhere to put files.

Maybe customers upload documents, your application generates PDFs, an ERP produces exports, or another system needs to retrieve files for processing. Whatever the use case, the basic requirement is often the same:


Application → Upload File → Cloud Storage → Download File


You do not necessarily need to build a storage platform around that requirement.

With ftpGrid, applications can upload, list, download, move and delete files through a REST API while ftpGrid provides the managed cloud file storage behind it. In this article, we'll keep it practical: authenticate, upload a file and download it again.


How to Upload and Download Files With a REST APIView larger infographic (AI generated image)



The architecture is deliberately simple

For an application using ftpGrid as file storage, the primary architecture can be as simple as:

┌──────────────────────┐
│ Your Application     │
└──────────┬───────────┘
           │
           │ HTTPS / REST API
           ▼
┌──────────────────────┐
│ ftpGrid              │
│ Cloud File Storage   │
└──────────────────────┘

Your application owns the business logic. ftpGrid handles the file storage.


That makes the model useful for:

  • Customer documents

  • Generated PDFs

  • Reports

  • Images

  • Application exports

  • Integration files

  • Data extracts

  • Backup files

  • Files exchanged with external systems


Let's put a file into storage.



Step 1: Authenticate your application

The ftpGrid Storage API uses bearer tokens for authentication. Your API credentials consist of an Association Key, Access Key and Secret Key. Your backend uses these credentials to obtain a temporary JWT access token.


The authentication payload looks like this:

{
  "AssociationKey": "YOUR_ASSOCIATION_KEY",
  "AccessKey": "YOUR_ACCESS_KEY",
  "SecretKey": "YOUR_SECRET_KEY"
}

After successful authentication, the response contains a token:

{
  "token": "eyJhbGc..."
}

Subsequent Storage API requests include the token in the standard HTTP authorization header:

Authorization: Bearer YOUR_TOKEN

Keep the long-lived API credentials on your backend. They should not be embedded in frontend JavaScript, mobile applications or other software distributed to end users.


The resulting flow is:


API credentials → JWT token → Storage API



Step 2: Upload a file with curl

Files are uploaded using multipart/form-data.


A simple upload can be performed with curl:

curl -X POST "https://webN.ftpgrid.com/api/upload" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@./invoice.pdf"

Replace webN.ftpgrid.com with the storage endpoint assigned to your ftpGrid account.


The important part is the file itself:

file=@./invoice.pdf

Your application sends the file over HTTPS and ftpGrid stores it in the managed file environment.


Conceptually:

invoice.pdf
     │
     ▼
REST API
     │
     ▼
ftpGrid Storage


There is no mounted filesystem or storage server for your application to operate.



Step 3: Organize application files

Real applications rarely put every file in one directory.


A SaaS application might organize files by customer:

/customers/1842/
/customers/1842/invoices/
/customers/1842/reports/
/customers/3921/invoices/

An integration platform might instead use:

/incoming/
/processing/
/processed/
/exports/

The important design decision is to choose a directory structure based on your application's domain rather than the underlying storage technology.


For example:

/customers/1842/invoices/invoice-2026-1042.pdf

Your application knows that customer 1842 owns the invoice. ftpGrid simply stores the file. This separation keeps storage infrastructure out of your application logic.



Step 4: List files before downloading

Applications often need to discover what is currently stored.


The Storage API can list files within a directory.


For example:

curl -X POST "https://webN.ftpgrid.com/api/list/files" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"Params":"/customers/1842/invoices/"}'

A response can contain information such as:

[
  {
    "lastModified": 1778904174199,
    "name": "invoice-2026-1042.pdf",
    "size": 184642,
    "type": "file"
  }
]

Your application can use file listings to:

  • Display available documents

  • Discover incoming integration files

  • Verify generated exports

  • Build administrative file views

  • Check whether processing output exists

  • Synchronize application state


The REST API provides the storage operations. Your application determines what the files mean.



Step 5: Download the file

A stored file can be downloaded through the API using its path.


For example:

curl -X POST \
  "https://webN.ftpgrid.com/api/download/single?path=/customers/1842/invoices/invoice-2026-1042.pdf" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --output invoice-2026-1042.pdf

The response is written directly to:

invoice-2026-1042.pdf

The complete workflow is now:

Application
    │
    │ Upload
    ▼
ftpGrid Storage
    │
    │ Download
    ▼
Application


For many business applications, that is the fundamental storage requirement.



Upload and download files from Go

The same operations can naturally be performed from application code.


Here is a compact Go example for downloading a file once your application has obtained a JWT token:

func downloadFile(token, filePath, outputPath string) error {
	url := "https://webN.ftpgrid.com/api/download/single?path=" + url.QueryEscape(filePath)

	req, err := http.NewRequest(http.MethodPost, url, nil)
	if err != nil {
		return err
	}

	req.Header.Set("Authorization", "Bearer "+token)

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("download failed: %s", resp.Status)
	}

	out, err := os.Create(outputPath)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, resp.Body)
	return err
}

The application does not need to know how the underlying storage infrastructure is implemented.


It only needs:

  • The storage endpoint

  • An access token

  • The file path


That is exactly the abstraction we want from application storage.



Upload files from Go

Uploading uses a standard multipart HTTP request.


A simplified implementation looks like this:

func uploadFile(token, filePath string) error {
	file, err := os.Open(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	var body bytes.Buffer
	writer := multipart.NewWriter(&body)

	part, err := writer.CreateFormFile("file", filepath.Base(filePath))
	if err != nil {
		return err
	}

	if _, err = io.Copy(part, file); err != nil {
		return err
	}
	writer.Close()

	req, err := http.NewRequest(http.MethodPost, "https://webN.ftpgrid.com/api/upload", &body)
	if err != nil {
		return err
	}

	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return fmt.Errorf("upload failed: %s", resp.Status)
	}

	return nil
}

In a production application, you would typically wrap authentication, upload, download and other storage operations in a small storage client rather than spreading HTTP calls throughout the application.


Your business code can then work with operations such as:

storage.Upload(...)
storage.Download(...)
storage.List(...)
storage.Delete(...)


The rest of the application does not need to care how those operations are implemented.



Keep authorization in your application

Storage authentication and application authorization are two different things.


Suppose customer 1842 requests:

/customers/1842/invoices/invoice-2026-1042.pdf

Your application should first determine whether the logged-in user is actually allowed to access that invoice.


Only then should the backend retrieve the file.


A typical architecture is therefore:

User
 │
 ▼
Your Application
 │
 ├─ Authenticate user
 ├─ Check business permissions
 │
 ▼
ftpGrid REST API
 │
 ▼
File

Do not expose your ftpGrid API credentials directly to the user simply because the user needs access to a stored file. Your application owns customer authorization. ftpGrid provides the managed storage behind it.



REST API on one side, FTP or SFTP on the other

Application storage becomes particularly useful when files do not exclusively come from your own software.


Imagine your application processes files from a business partner.


Your application prefers REST:

Application → REST API → ftpGrid

But the partner already has an established SFTP integration:

Partner → SFTP → ftpGrid

Those workflows can meet in the same managed file environment:

Application ── REST API ──┐
                          │
Partner ───── SFTP ───────┼──→ ftpGrid Storage
                          │
Legacy ERP ── FTP ────────┘

There is no business benefit in forcing every external system to implement your preferred API. Modern applications can use REST while existing systems continue using FTP or SFTP.



Let your application know when a file arrives

If another system uploads files, your application needs a way to know when something has changed.


Polling works:

Application → List files → Wait → List files → Wait...

But event-driven integration is often cleaner:

Partner
   │
   │ SFTP
   ▼
ftpGrid
   │
   │ Webhook
   ▼
Your Application

A supplier can upload through SFTP, for example, and ftpGrid can trigger a webhook so your application knows that it should begin processing. This combines traditional business file transfer with modern application integration. Learn more about ftpGrid webhooks.



You need file storage — not another infrastructure project

Uploading and downloading files is not a complicated application requirement. The infrastructure surrounding file storage can be.


If your requirement is:

“My application needs somewhere reliable to put files.”

then a focused architecture can be enough:


Application → REST API → Managed Cloud Storage


ftpGrid provides that storage while also supporting the wider file workflows businesses tend to accumulate over time. Your application can use REST. Your ERP can use FTP. Your partners can use SFTP. Webhooks can notify your application when files arrive. You can therefore start with the simplest requirement — upload and download a file — without designing an entire storage platform around it.


For a broader overview of building file workflows with the API, see the REST API tutorial. Store the file. Get it back when you need it. Let the storage platform handle the rest.



Start in 30 seconds