When you upload from the server
This guide uses Node.js, and the steps have the Ruby, Python, PHP and cURL version in a tab. Browser uploads cover user files. Server-side uploads cover everything else: importing an existing archive, saving a PDF your code generated, copying images from a third-party feed, or a nightly job that mirrors files. The same hosted storage and the same IDs apply, so a file you upload here is shown in your app like any other.
Set up the client
npm install @cd2/fileboy-nodebundle add fileboypip install fileboycomposer require fileboy/fileboyOn the server, give the client your private key as well as your public key. Requests it makes are signed with that key. Keep the private key in an environment variable and never ship it to a browser.
import { Fileboy } from "@cd2/fileboy-node"
const fileboy = Fileboy({
publicKey: process.env.FILEBOY_PUBLIC_KEY!,
privateKey: process.env.FILEBOY_PRIVATE_KEY!,
})require "fileboy"
fileboy = Fileboy::Client.new(
public_key: ENV.fetch("FILEBOY_PUBLIC_KEY"),
private_key: ENV["FILEBOY_PRIVATE_KEY"]
)import os
import fileboy
client = fileboy.Client(
public_key=os.environ["FILEBOY_PUBLIC_KEY"],
private_key=os.environ.get("FILEBOY_PRIVATE_KEY"),
)use Fileboy\Client;
$fileboy = new Client(
publicKey: getenv('FILEBOY_PUBLIC_KEY'),
privateKey: getenv('FILEBOY_PRIVATE_KEY') ?: null,
);From a path on disk
const file = await fileboy.uploadFileFromPath("./exports/report.pdf", {
metadata: { customerId: "cus_123", kind: "monthly-report" },
})
console.log(file.id) // save thisfile = fileboy.upload_file(
"./exports/report.pdf",
metadata: { customerId: "cus_123", kind: "monthly-report" }
)
puts file.id # save thisfile = client.upload_file(
"./exports/report.pdf",
metadata={"customerId": "cus_123", "kind": "monthly-report"},
)
print(file.id) # save this$file = $fileboy->uploadFile(
'./exports/report.pdf',
metadata: ['customerId' => 'cus_123', 'kind' => 'monthly-report'],
);
echo $file->id; // save thiscurl https://api.fileboy.io/files/upload \
-H "Authorization: public YOUR_PUBLIC_KEY" \
-F "file=@./exports/report.pdf" \
-F 'data={"name":"report.pdf","metadata":{"kind":"monthly-report"}}'From a buffer or a stream
When the data is not on disk, pass it directly. Name the file, because data in memory has no name of its own.
// a Buffer you generated
const invoice = await fileboy.uploadFile(pdfBuffer, {
name: "invoice-1042.pdf",
mime: "application/pdf",
})# any IO: a StringIO, a Tempfile, an open File
invoice = fileboy.upload_file(
StringIO.new(pdf_data),
name: "invoice-1042.pdf",
mime: "application/pdf"
)# bytes, or any binary file object
invoice = client.upload_file(
pdf_bytes,
name="invoice-1042.pdf",
mime="application/pdf",
)// a stream: any open resource, or a PSR-7 stream
$stream = fopen('php://temp', 'r+');
fwrite($stream, $pdfData);
rewind($stream);
$invoice = $fileboy->uploadFile($stream, name: 'invoice-1042.pdf', mime: 'application/pdf');From a remote URL
Fileboy fetches the file itself, so it never passes through your machine. Use expect to refuse anything that is not the type you meant to import.
const photo = await fileboy.uploadFileFromUrl("https://example.com/photo.jpg", {
name: "photo.jpg",
expect: "image/jpeg",
})photo = fileboy.upload_file_from_url(
"https://example.com/photo.jpg",
name: "photo.jpg",
expect: "image/jpeg"
)photo = client.upload_file_from_url(
"https://example.com/photo.jpg",
name="photo.jpg",
expect="image/jpeg",
)$photo = $fileboy->uploadFileFromUrl(
'https://example.com/photo.jpg',
name: 'photo.jpg',
expect: 'image/jpeg',
);curl https://api.fileboy.io/files/upload \
-H "Authorization: public YOUR_PUBLIC_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/photo.jpg","name":"photo.jpg","expect":"image/jpeg"}'Only public, internet-reachable addresses can be fetched this way. URLs that point at internal or private network addresses are refused.
Read a file's details and build URLs
// the details of one file: name, mime, size, hash, metadata
const data = await fileboy.fetchFileData(file.id)
// a URL for a file or an image
const link = fileboy.buildFileUrl(file.id, { download: true })
const thumb = fileboy.buildImageUrl(photo.id, {
transforms: [{ type: "resize", width: 300 }],
})# the details of one file: name, mime, size, hash, metadata
data = fileboy.fetch_file_data(file.id)
# a URL for a file or an image
link = fileboy.build_file_url(file.id, download: true)
thumb = fileboy.build_image_url(photo.id, transforms: [{ type: :resize, width: 300 }])# the details of one file: name, mime, size, hash, metadata
data = client.fetch_file_data(file.id)
# a URL for a file or an image
link = client.build_file_url(file.id, download=True)
thumb = client.build_image_url(photo.id, transforms=[{"type": "resize", "width": 300}])// the details of one file: name, mime, size, hash, metadata
$data = $fileboy->fetchFileData($file->id);
// a URL for a file or an image
$link = $fileboy->buildFileUrl($file->id, download: true);
$thumb = $fileboy->buildImageUrl($photo->id, transforms: [['type' => 'resize', 'width' => 300]]);curl https://api.fileboy.io/files/data/FILE_IDSave the returned id in your own database next to the record it belongs to. Metadata is stored with the file and returned in its details, but treat it as a note, not as your source of truth. See the Node library docs for the rest of the client.
Checked against the current libraries in November 2026. Found something that no longer works? Tell us.