Upload flows
Automatic Cooking
This is the standard path. The creator uploads one source file and cooking happens automatically across all enabled platforms.
This path is used by the cfeditor upload widget and by most studio integrations.
FCreateModFileRequest Request;
Request.changelog = TEXT("Initial release");
Request.changelogType = ECFCoreChangelogMarkupType::Text;
Request.displayName = TEXT("My Mod v1.0");
Request.releaseType = ECFCoreFileReleaseType::Release;
// Mark as source file for cloud cooking
Request.cookingOptions.isSourceFile = true;
Request.cookingOptions.autoCookingType = ECFCoreAutoCookingType::All;
// optionally pin to a specific cooker version:
// Request.cookingOptions.cookerVersion = TEXT("1.2.3");
CFCoreContext::GetInstance()->ApiCreation()->CreateModFile(
ModId,
Request,
FileData, // TSharedPtr<TArray<uint8>>
[](const FFileTransferProgress& Progress) {
// upload progress callback
},
[](const TOptional<FUploadedModFile>& File,
const TOptional<FCFCoreApiResponseError>& Error) {
if (File.IsSet()) {
// file uploaded — cooking will start automatically
}
});
Blueprint: Use the Create Mod File node with cookingOptions.isSourceFile = true.
Large Files (Chunked Upload)
For files larger than approximately 1 GB, use the chunked upload variant. Recommended chunk size is 100 MB or less.
// Step 1: initiate chunked upload session
CFCoreContext::GetInstance()->ApiCreation()->CreateModFileChunked(
ModId, Request,
[](const TOptional<FModFileChunkedInfo>& Info,
const TOptional<FCFCoreApiResponseError>& Error) {
// Use Info to get upload URL, then call UploadModFileChunk per chunk
});
// Step 2: upload each chunk
CFCoreContext::GetInstance()->ApiCreation()->UploadModFileChunk(
ChunkMetadata, ChunkData,
[](const FFileTransferProgress& Progress) { },
[](const bool& bSuccess,
const TOptional<FCFCoreApiResponseError>& Error) { });
Blueprint: Use Create Mod File Chunked followed by repeated Upload Mod File Chunk calls.
Manual Cooking
Manual cooking (ECFCoreAutoCookingType::Manual) is the path for studios that want to produce and verify cooked outputs locally before submitting them, rather than relying on the automatic pipeline.
This requires a full editor build with access to the relevant platform SDKs.
The process is three steps:
- Upload the source file with
autoCookingType = Manual. - Cook locally using your editor build with platform SDKs installed.
- Upload each cooked output explicitly, associated with the source file ID.
// Step 1: upload source file (no auto-cooking)
FCreateModFileRequest SourceRequest;
SourceRequest.cookingOptions.isSourceFile = true;
SourceRequest.cookingOptions.autoCookingType = ECFCoreAutoCookingType::Manual;
// ...upload SourceRequest, receive SourceFileId in callback...
// Step 2: upload cooked output for each target platform
FCreateCookedModFileRequest CookedRequest;
CookedRequest.platform = ECFCorePlatform::PS5;
CFCoreContext::GetInstance()->ApiCreation()->CreateCookedModFile(
ModId,
SourceFileId, // from Step 1
CookedRequest,
CookedFileData,
[](const FFileTransferProgress& Progress) { },
[](const TOptional<FUploadedModFile>& File,
const TOptional<FCFCoreApiResponseError>& Error) { });
Author restriction. Only the user who uploaded the source file can associate cooked files with it. Attempts by other users return error kModFileAuthorMismatch (1107).
Publishing Control
By default, a mod file publishes automatically once it clears moderation (Approved → Released). To hold a file for manual release, for example to coordinate a timed launch or a content drop, set isMarkedForManualRelease = true on the upload request:
Request.isMarkedForManualRelease = true;
The file reaches AwaitingPublishing status after approval and remains there until you release it manually via the Developer Portal.
This is the recommended approach for coordinated launches where multiple mod files or game updates need to go live simultaneously.
Cooker Version Management
Each cooked file records which cooker version produced it via FFileCookingInfo.cookerVersion.
When your game ships a major engine update, CurseForge can trigger a full catalog recook from the Developer Portal. All existing source files in your catalog are re-run through the updated cooker, producing new platform-ready outputs without any action required from mod creators.
This is the central long-term stability guarantee: creators submit once, and CurseForge keeps all cooked outputs current with your game's engine version. Your mod catalog does not go stale.
Pinning a specific cooker version
If you need a batch of uploads to target a specific engine build, set cookerVersion on the upload request rather than leaving it empty:
Request.cookingOptions.cookerVersion = TEXT("1.2.3");
The current active version can be queried at any time:
GET /v1/cooking/sdk-version