Files (images, audio, PDFs, any binary data) are stored next to your app and served from a CDN. An object refers to a file through a File field; the file itself is uploaded once and can be referenced by many objects.
Upload
const input = document.querySelector('#avatar'); // <input type="file">
const file = new Parse.File('avatar.jpg', input.files[0]);
await file.save();
const user = Parse.User.current();
user.set('avatar', file);
await user.save();
console.log(file.url()); // https://<id>.files-sashido.cloud/...
From other sources: new Parse.File(name, { base64: '...' }), or bytes on Node.js. Every SDK has the same File type: see Parse's guides for iOS, Android and REST.
Parse adds a unique prefix to each file's name, so two uploads of avatar.jpg never overwrite each other.
Serve
file.url() is the file's address on the CDN (App Settings › Security & Keys › Files URL (CDN)). Show it in an <img>, link to it, or hand it to a video player.
File URLs are public: anyone with the URL can download the file. The file name's random prefix makes URLs hard to guess, but for private documents, don't hand out the URL: serve them through a cloud function that checks the user first.
Limits and pricing
- Up to 20 MB per file. For larger files, contact support.
- Storage and data transfer are billed by use: see pricing.
- Compress images and videos on the client before uploading: it saves storage, transfer and your users' time.
Delete
Deleting an object doesn't delete the files it refers to (another object may use them). Delete a file with the master key, typically in an afterDelete trigger:
Parse.Cloud.afterDelete('Photo', async (request) => {
const file = request.object.get('image');
if (file) {
await file.destroy({ useMasterKey: true });
}
});
From scripts and AI assistants
POST files/<name> through the Management API's Parse proxy uploads up to 10 MB with an access token. Through MCP, upload_file takes the content directly; the local server can also upload from a path or a URL.