← Back to all posts
(Updated March 2026)6 min readCentrali Team

Store Files from Functions: PDFs, Images, and More

Save binary files — PDFs, images, API responses — directly from compute functions. Generate shipping labels, invoices, or reports on demand without leaving Centrali.

FeatureComputeTutorial

Functions are great for processing data and calling APIs. But what happens when those APIs return binary files like PDFs, images, or documents?

Previously, you'd need to store file references and fetch them separately, or pass base64 data through your client. Neither option is ideal.

Now you can store files directly from functions with api.storeFile().

Basic Usage

typescript
const result = await api.storeFile(
pdfBase64Content, // File content
"shipping-label.pdf", // Filename
{
mimeType: "application/pdf", // Required
encoding: "base64" // "base64" or "utf8"
}
);
if (result.success) {
api.log(`Stored: ${result.fileUrl}`);
// Save URL to your record
await api.updateRecord(orderId, {
shippingLabelUrl: result.fileUrl
});
}

Real Example: DHL Shipping Labels

One of the most common use cases is storing shipping labels from carrier APIs:

typescript
async function run() {
const order = await api.fetchRecord(executionParams.orderId);
// Call DHL to generate label
const dhlResponse = await api.httpPost('https://api.dhl.com/parcel/labels', {
headers: {
'Authorization': `Bearer ${triggerParams.dhlApiKey}`
},
data: {
shipperAddress: triggerParams.warehouseAddress,
recipientAddress: order.data.shippingAddress,
weight: order.data.totalWeight,
service: 'EXPRESS'
}
});
// DHL returns base64-encoded PDF
const labelBase64 = dhlResponse.labelImage;
// Store it in Centrali
const result = await api.storeFile(
labelBase64,
`dhl-label-${order.data.orderNumber}.pdf`,
{
mimeType: "application/pdf",
encoding: "base64",
folder: "/shipping-labels"
}
);
// Update order with label URL
await api.updateRecord(executionParams.orderId, {
shippingLabelUrl: result.fileUrl,
trackingNumber: dhlResponse.trackingNumber,
status: 'shipped'
});
return {
success: true,
data: { trackingNumber: dhlResponse.trackingNumber }
};
}

Parameters

ParameterRequiredDescription
contentYesFile content (string)
filenameYesName for the file
options.mimeTypeYesMIME type (e.g., "application/pdf")
options.encodingNo"base64" or "utf8" (default: "utf8")
options.folderNoTarget folder (default: "/root/shared")
options.isPublicNoPublic access (default: false)

Return Value

typescript
// Success
{
success: true,
fileUrl: "https://storage.centrali.io/workspace/...",
renderId: "abc123..."
}
// Error
{
success: false,
error: "File size exceeds 100MB limit"
}

More Use Cases

Generated Reports

typescript
// Generate HTML report
const html = api.renderTemplate(reportTemplate, {
orders: executionParams.orders,
date: new Date().toISOString()
});
// Store as HTML file
const result = await api.storeFile(
html,
`sales-report-${api.dayjs().format('YYYY-MM-DD')}.html`,
{
mimeType: "text/html",
encoding: "utf8", // UTF-8 for text
folder: "/reports/sales"
}
);

Downloaded Images

typescript
// Download product image from supplier
const imageResponse = await api.httpGet(
supplierImageUrl,
{ responseType: 'base64' }
);
// Store in Centrali
const result = await api.storeFile(
imageResponse.data,
`product-${sku}.jpg`,
{
mimeType: "image/jpeg",
encoding: "base64",
folder: "/products/images",
isPublic: true // For public product pages
}
);

Invoice PDFs

typescript
// Generate invoice with PDF service
const pdfResponse = await api.httpPost('https://api.pdfshift.io/v3/convert', {
headers: {
'Authorization': `Basic ${api.base64.encode(`api:${triggerParams.pdfshiftKey}`)}`
},
data: {
source: invoiceHtml,
landscape: false,
format: 'A4'
}
});
// Store the PDF
const result = await api.storeFile(
pdfResponse.data,
`invoice-${invoiceNumber}.pdf`,
{
mimeType: "application/pdf",
encoding: "base64",
folder: `/invoices/${year}`
}
);

Public vs Private Files

typescript
// Private (default) - requires auth to access
await api.storeFile(content, "invoice.pdf", {
mimeType: "application/pdf",
isPublic: false
});
// Public - anyone with URL can access
await api.storeFile(content, "product-photo.jpg", {
mimeType: "image/jpeg",
isPublic: true
});

Error Handling

Always check the result:

typescript
const result = await api.storeFile(content, filename, options);
if (!result.success) {
api.logError({
message: 'Failed to store file',
error: result.error,
filename
});
return { success: false, error: result.error };
}
// Continue with success flow

Limits

  • Maximum file size: 100 MB
  • Supported encodings: base64, utf8

Summary

api.storeFile() makes it easy to save files from functions:

  1. Call external API that returns a file
  2. Store it with api.storeFile()
  3. Save the URL to your records

No more workarounds, no more client-side file handling for server operations.

Check the functions guide for more examples.

Building something with Centrali and want to share feedback about this feature?

Email feedback@centrali.io