Rails File Upload

Upload Files from Rails Controllers Without Active Storage

Upload files from Rails controllers with net/http. No SDK, REST API, CDN delivery.

Active Storage with an S3 service is the default Rails answer, but it is a lot of machinery — a service config, two extra tables, blob/attachment records, and a direct-upload JS controller — when all you want is to send a file somewhere and get back a CDN URL. files.link is three HTTP calls from a controller, no Active Storage, no aws-sdk-s3 gem, no storage.yml.

And because it is just HTTP, the same code runs from a Sidekiq job, a rake task, or a one-off script — places where Active Storage's record dependencies get awkward.

The browser posts multipart/form-data; Rails hands you an ActionDispatch::Http::UploadedFile via params[:upload]. You read its bytes and PUT them to the presigned URL.

ruby
require 'net/http'

class UploadsController < ApplicationController
  KEY = Rails.application.credentials.fileslink_key
  BASE = 'https://api.files.link'

  def create
    file = params[:upload]
    bytes = file.read
    meta = { filesMetadata: [{ name: file.original_filename, size: bytes.bytesize, type: file.content_type }] }
    r1 = Net::HTTP.post(URI("#{BASE}/v1/files/#{ENV['FILESLINK_FOLDER']}"),
         meta.to_json, 'Authorization' => KEY, 'Content-Type' => 'application/json')
    slot = JSON.parse(r1.body)['urls'].first

    put = Net::HTTP.new(URI(slot['url']).host, 443); put.use_ssl = true
    put.send_request('PUT', URI(slot['url']).request_uri, bytes, 'Content-Type' => file.content_type)

    Net::HTTP.post(URI("#{BASE}/v1/files/confirm-upload"),
         { ids: [slot['id']] }.to_json, 'Authorization' => KEY, 'Content-Type' => 'application/json')
    render json: { id: slot['id'] }
  end
end

Prefer HTTParty or Faraday? Swap the three net/http calls for their equivalents; the endpoints and bodies are unchanged. The Authorization header carries the raw API key — no Bearer prefix — and the cleanest place for that key is Rails encrypted credentials (Rails.application.credentials.fileslink_key), never a hardcoded string. For anything but tiny files, push the three-call flow into an ActiveJob/Sidekiq job so the controller responds instantly and the upload finishes in the background; pass a Tempfile path rather than raw bytes to keep the job payload small. files.link and Active Storage do not collide — you can keep Active Storage for some attachments and use files.link for CDN-served public assets.

Files come back as CDN URLs with per-file visibility, encrypted at rest, billed from prepaid credits.

Benefits With No Complexity

Global CDN delivery

Your files are served from 450+ edge locations worldwide.

Edge-cached worldwide

Files are cached close to your users for fast delivery.

Signed-URL security

Private files stay protected with time-limited access.

What You Get

Unlimited files

Upload as many files as you need.

Unlimited storage

There is no storage limit.

Public + Private storage

Private files are fully secured.

CDN ready links

Upload directly to 450+ edge locations worldwide.

Prepaid credits

No subscription. Pay only for the storage and bandwidth you use.

More coming soon

We have plenty of features coming!

How files.link Works

1. Upload

Create a project and upload your first file.

2. Copy

Copy the CDN link.

3. Use Anywhere

Paste and enjoy the blazing speed.

Why Developers Choose files.link

A Better Way to Store & Deliver Files

Active Storage + S3Cloudinary (cloudinary gem)files.link
No Active Storage config or extra tables
Works in jobs, rake tasks, scripts
Global CDN delivery on every file
No aws-sdk-s3 gem / IAM setup
Prepaid credits (no surprise bills)

Calculate Your Needs

Storage

0GB

Egress

0GB

CDN Bandwidth

0GB
Total: $0.000/month

Wire Up Rails File Uploads

  • Global CDN delivery
  • Edge-cached worldwide
  • Signed-URL security
  • Unlimited files
  • Unlimited storage
  • Public + Private storage
  • No subscription — prepaid credits keep spend predictable
Start Uploading from Rails

Frequently Asked Questions

Do I have to use Active Storage?
No. files.link is plain HTTP, so you skip storage.yml, the active_storage_blobs/attachments tables, and the direct-upload JS. You can still use Active Storage for other attachments — the two do not conflict.
How do I get the uploaded file in a Rails controller?
It arrives as params[:upload], an ActionDispatch::Http::UploadedFile. Call .read for the bytes (or use .tempfile.path for large files), then PUT those bytes to the presigned URL.
Where should the API key live in Rails?
In encrypted credentials: Rails.application.credentials.fileslink_key. Pass it as the raw Authorization header value — files.link uses no Bearer prefix — and never hardcode it.
How do I upload in the background?
Wrap the three-call flow in an ActiveJob and enqueue it from the controller via perform_later. Pass a Tempfile path instead of raw bytes so the Sidekiq payload stays small, and the controller returns immediately.
Can I use HTTParty or Faraday instead of net/http?
Yes. The example uses stdlib net/http to avoid any gem, but HTTParty and Faraday map one-to-one onto the same three calls — only the client syntax changes.
General Questions
Is there a subscription?
No. files.link uses prepaid credits, so storage, bandwidth, and API usage are deducted from your balance as you go. The app explains the payment step before uploads are enabled — no monthly subscription and no per-user fees.
What is files.link?
files.link is a developer-first file platform that makes it simple to store, secure, and deliver files globally. It provides signed URLs, public/private access, and an API-first design so you can integrate file delivery into any app without the usual complexity.
How does billing work?
files.link uses prepaid credits. As you use storage, bandwidth, and API requests, credits are deducted daily. When your balance runs low, we automatically recharge it using your saved card. If an auto-recharge doesn't go through, your files and links stay put — you simply update your payment method or top up manually to keep going. No monthly subscriptions — just simple usage-based pricing.
How secure is my data?
All files are encrypted at rest and in transit. You can use signed URLs for private files, control access with permissions, and rely on enterprise-grade infrastructure for data protection.

Related

files.link
Copyright © 2026
All rights reserved
ContactGuidesGlossaryStatusLegal