Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.whop.com/llms.txt

Use this file to discover all available pages before exploring further.

Upload files to Whop for use in courses, forums, profiles, and more. The SDK provides a simple upload method that handles the entire process for you.
import fs from 'fs';

const file = await client.files.upload({
  file: fs.readFileSync('./photo.jpg'),
  filename: 'photo.jpg',
});

console.log(file.id); // file_xxxxxxxxxxxxx
console.log(file.url); // URL to access the file
The upload method:
  1. Creates a file record with a presigned URL
  2. Uploads your file to storage
  3. Polls until processing is complete
  4. Returns the ready file with its final URL

Public vs private files

Every file you upload has a visibility that controls how it can be accessed. You choose visibility at upload time — it cannot be changed after.
VisibilityURL typeWho can accessUse for
public (default)Permanent, unsigned CDN URLAnyone with the linkProduct images, thumbnails, branding, marketing assets
privateSigned URL that expiresOnly your app, via the APIUser-uploaded documents, sensitive content, AI-generated files
Choose carefully. Public files are cached on our CDN and accessible to anyone with the URL — there is no way to revoke access. If the content is user-specific or sensitive, use private.

Uploading a private file

Pass visibility: "private" when creating the file:
const file = await client.files.upload({
  file: fs.readFileSync('./user-document.pdf'),
  filename: 'user-document.pdf',
  visibility: 'private',
});

// file.url is a signed URL that expires — fetch it fresh via
// client.files.retrieve(file.id) whenever you need a new one

Accessing private files

Private file URLs expire. To get a fresh URL, retrieve the file by ID:
const file = await client.files.retrieve(fileId);
console.log(file.url); // fresh signed URL

Using uploaded files

Once uploaded, use the file ID in any API call that accepts file attachments:
await client.courses.update({
	id: "course_xxx",
	thumbnail: { id: file.id },
});

File properties

PropertyDescription
idUnique identifier (e.g., file_xxxxxxxxxxxxx)
filenameOriginal filename
content_typeMIME type (e.g., image/jpeg)
byte_sizeFile size in bytes
urlURL to access the file (signed and expiring for private files)
upload_statusStatus: pending, processing, ready, or failed
visibilitypublic or private