Integration Guide
Overview
Section titled “Overview”Integrating Uploadista Cloud into your app requires two things:
- A backend auth endpoint that exchanges your API key for a JWT token
- A client SDK configured in
uploadista-cloudmode
This guide covers the full setup with detailed examples for common frameworks and scenarios.
Authentication Flow
Section titled “Authentication Flow”Understanding the auth flow helps you integrate Uploadista Cloud correctly:
1. Client SDK needs to upload a file2. Client calls YOUR backend: GET /api/auth/token/:clientId3. Your backend calls Uploadista Cloud with your API key4. Uploadista Cloud returns a short-lived JWT token5. Your backend forwards the token to the client6. Client uses the token for all upload/flow requests7. Token is cached and auto-refreshed before expirationBackend Setup
Section titled “Backend Setup”Auth Endpoint
Section titled “Auth Endpoint”Your backend needs a single endpoint. The getAuthCredentials helper handles the token exchange with Uploadista Cloud:
import { getAuthCredentials } from '@uploadista/server/auth';import { getServerSession } from 'next-auth'; // or your auth library
export const GET = async (req: Request, ctx: { params: Promise<{ clientId: string }> }) => { // Protect the endpoint with your own auth const session = await getServerSession(); if (!session) { return Response.json({ error: "Unauthorized" }, { status: 401 }); }
const { clientId } = await ctx.params;
const response = await getAuthCredentials({ uploadistaClientId: clientId, uploadistaApiKey: process.env.UPLOADISTA_API_KEY!, });
if (!response.isValid) { return Response.json({ error: response.error }, { status: 500 }); }
return Response.json(response.data);};import { getAuthCredentials } from '@uploadista/server/auth';
// Protect with your auth middlewareapp.get('/api/auth/token/:clientId', requireAuth, async (req, res) => { const response = await getAuthCredentials({ uploadistaClientId: req.params.clientId, uploadistaApiKey: process.env.UPLOADISTA_API_KEY!, });
if (!response.isValid) { return res.status(500).json({ error: response.error }); }
res.json(response.data);});import { getAuthCredentials } from '@uploadista/server/auth';
app.get('/api/auth/token/:clientId', authMiddleware, async (c) => { const response = await getAuthCredentials({ uploadistaClientId: c.req.param('clientId'), uploadistaApiKey: c.env.UPLOADISTA_API_KEY, });
if (!response.isValid) { return c.json({ error: response.error }, 500); }
return c.json(response.data);});import { getAuthCredentials } from '@uploadista/server/auth';
fastify.get('/api/auth/token/:clientId', { preHandler: [fastify.authenticate], // your auth hook}, async (request, reply) => { const { clientId } = request.params as { clientId: string };
const response = await getAuthCredentials({ uploadistaClientId: clientId, uploadistaApiKey: process.env.UPLOADISTA_API_KEY!, });
if (!response.isValid) { return reply.status(500).send({ error: response.error }); }
return response.data;});Environment Variables
Section titled “Environment Variables”Add these to your backend environment:
# Your Uploadista Cloud API key (from Settings > API Keys)UPLOADISTA_API_KEY=upl_sk_...Client Setup
Section titled “Client Setup”import { UploadistaProvider, useUpload, useFlow } from "@uploadista/react";
function App() { return ( <UploadistaProvider storageId="your-storage-id" auth={{ mode: 'uploadista-cloud', authServerUrl: '/api/auth/token', clientId: process.env.NEXT_PUBLIC_UPLOADISTA_CLIENT_ID! }} > <FileUploader /> </UploadistaProvider> );}
// Simple uploadfunction FileUploader() { const upload = useUpload({ onSuccess: (result) => { console.log("File URL:", result.url); }, });
return ( <div> <input type="file" onChange={(e) => { const file = e.target.files?.[0]; if (file) upload.upload(file); }} /> {upload.isUploading && <progress value={upload.state.progress} max={100} />} </div> );}
// Upload with flow processingfunction ImageProcessor() { const flow = useFlow({ flowConfig: { flowId: "image-optimization", storageId: "your-storage-id", }, onSuccess: (outputs) => { console.log("Processed files:", outputs); }, });
return ( <div> <input type="file" accept="image/*" onChange={(e) => { const file = e.target.files?.[0]; if (file) flow.upload(file); }} /> {flow.isUploading && ( <div> <progress value={flow.state.progress} max={100} /> {flow.state.currentNodeName && <p>Processing: {flow.state.currentNodeName}</p>} </div> )} </div> );}See the full React SDK reference for all hooks and components.
import { createUploadistaPlugin } from "@uploadista/vue";
app.use(createUploadistaPlugin({ storageId: "your-storage-id", auth: { mode: 'uploadista-cloud', authServerUrl: '/api/auth/token', clientId: import.meta.env.VITE_UPLOADISTA_CLIENT_ID }}));<script setup lang="ts">import { useUpload } from "@uploadista/vue";
const upload = useUpload({ onSuccess: (result) => { console.log("File URL:", result.url); },});
function handleFileSelect(event: Event) { const file = (event.target as HTMLInputElement).files?.[0]; if (file) upload.upload(file);}</script>
<template> <div> <input type="file" @change="handleFileSelect" /> <progress v-if="upload.isUploading" :value="upload.state.progress" max="100" /> </div></template>See the full Vue SDK reference for all composables.
Expo / React Native
Section titled “Expo / React Native”import { createUploadistaClient } from "@uploadista/expo";
const client = createUploadistaClient({ storageId: "your-storage-id", auth: { mode: 'uploadista-cloud', authServerUrl: 'https://api.yourapp.com/auth/token', clientId: 'your-client-id' }});
// Upload a fileconst result = await client.upload(file);console.log("File URL:", result.url);See the full Expo SDK reference for mobile-specific features.
Using Flows
Section titled “Using Flows”Flows created in the Uploadista Cloud dashboard are available to your client SDK by their flow ID.
Creating Flows in the Dashboard
Section titled “Creating Flows in the Dashboard”- Go to Flows in your dashboard
- Click Create Flow
- Drag nodes from the sidebar (Input, Resize, Save, etc.)
- Connect nodes by dragging between handles
- Click each node to configure it (dimensions, format, storage)
- Click Test to verify with a sample file
- Save and Activate the flow
Triggering Flows from Code
Section titled “Triggering Flows from Code”Once a flow is active, trigger it from your client with the flow ID:
import { useFlow } from "@uploadista/react";
function ProfilePictureUpload() { const flow = useFlow({ flowConfig: { flowId: "profile-picture-resize", // Flow ID from the dashboard storageId: "your-storage-id", }, onSuccess: (outputs) => { // outputs contains the processed file URLs updateUserAvatar(outputs.thumbnail.url); }, });
return ( <input type="file" accept="image/*" onChange={(e) => { const file = e.target.files?.[0]; if (file) flow.upload(file); }} /> );}import { Flow } from "@uploadista/react";
function ProfilePictureUpload() { return ( <Flow flowId="profile-picture-resize" storageId="your-storage-id" onSuccess={(outputs) => updateUserAvatar(outputs.thumbnail.url)} > <Flow.DropZone accept="image/*"> {({ isDragging, getRootProps, getInputProps }) => ( <div {...getRootProps()}> <input {...getInputProps()} /> {isDragging ? "Drop your photo" : "Click or drag to upload"} </div> )} </Flow.DropZone>
<Flow.Status> {({ status, currentNodeName }) => ( <p>{status === "processing" ? `Processing: ${currentNodeName}` : status}</p> )} </Flow.Status>
<Flow.Error> {({ hasError, message, reset }) => hasError && ( <div> <p>Error: {message}</p> <button onClick={reset}>Try again</button> </div> ) } </Flow.Error> </Flow> );}Common Flow Patterns
Section titled “Common Flow Patterns”| Flow | What it does | Typical nodes |
|---|---|---|
| Profile picture | Resize + crop to square + save as WebP | Input > Resize > Crop > Format Convert > Save |
| Product images | Generate thumbnail + full-size + optimize | Input > Resize (x2) > Optimize > Save (x2) |
| Document upload | Validate type + store securely | Input > Conditional > Save |
| Image gallery | Multiple sizes + watermark | Input > Resize (x3) > Watermark > Save (x3) |
Migrating from Self-Hosted
Section titled “Migrating from Self-Hosted”If you’re already using the self-hosted Uploadista SDK and want to switch to Cloud:
1. Switch the auth mode
Section titled “1. Switch the auth mode”Replace the direct auth config and baseUrl with uploadista-cloud mode:
<UploadistaProvider baseUrl="https://your-server.com" storageId="your-storage-id" auth={{ mode: 'direct', getCredentials: async () => ({ headers: { 'Authorization': `Bearer ${token}` } }) mode: 'uploadista-cloud', authServerUrl: '/api/auth/token', clientId: 'your-client-id' }}>2. Add the backend auth endpoint
Section titled “2. Add the backend auth endpoint”Add a single GET /api/auth/token/:clientId endpoint as described in Backend Setup.
3. Recreate flows in the dashboard
Section titled “3. Recreate flows in the dashboard”If you have code-defined flows, recreate them in the visual flow builder. The node types and configuration options are the same.
4. Update storage references
Section titled “4. Update storage references”Update your storage IDs to match the ones created in the Uploadista Cloud dashboard.
Troubleshooting
Section titled “Troubleshooting”Token exchange fails
Section titled “Token exchange fails”- Verify your
UPLOADISTA_API_KEYis set correctly - Check that the
clientIdin the client config matches a valid storage - Ensure your auth endpoint is accessible from the client
Uploads fail with 401
Section titled “Uploads fail with 401”- The token may have expired — check that auto-refresh is working
- Verify your auth endpoint returns the correct response format
- Check browser console for CORS errors
Flows not executing
Section titled “Flows not executing”- Verify the flow is activated in the dashboard
- Check that the
flowIdmatches exactly (case-sensitive) - Ensure the storage ID in
flowConfigexists in your account
Related
Section titled “Related”- Uploadista Cloud Overview — What Cloud offers
- Authentication — Auth modes in depth
- React Client — Full React SDK reference
- Vue Client — Full Vue SDK reference
- Expo Client — Full Expo SDK reference
- Flows Engine — How flows work