← Back to all posts
6 min readCentrali Team

Store Files from Compute Functions: PDFs, Images, and More

The new api.storeFile() method lets you save binary files directly from compute functions. Generate shipping labels, store API responses, or save generated reports.

FeatureComputeTutorial

Compute 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 compute 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 compute 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 compute functions guide for more examples.

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

Email feedback@centrali.io