Saving asset programatically, eg via API I'm working on a plugin in Craft 3 that is fetching a file reference (URL) via an API.

I want to fetch the file and save it locally as an Asset. I've tried to do this via Craft::$app-&gt;getElements()-&gt;saveElement() but am getting the following error:

New Location cannot be blank.

Any thoughts on this issue or where to dig a bit deeper to resolve?

Cole
Not an answer directly to your question but a general function to upload an asset in PHP. In my case $file is an uploaded file in the $_FILES array. You can download a file per url and insert it's tmp_name and name manually

/**
 * Upload a file
 *
 * @param $file
 * @return int|null|string
 * @throws \Throwable
 * @throws \craft\errors\ElementNotFoundException
 * @throws \yii\base\Exception
 */
public function uploadImage($file)
{
    $assets = Craft::$app-&gt;getAssets();
    $folderId = 1; //&lt;- insert your folder id

    /** @var \craft\models\VolumeFolder $folder */
    $folder = $assets-&gt;findFolder(['id' =&gt; $folderId]);

    $asset = new Asset();
    $asset-&gt;tempFilePath = $file['tmp_name'];
    $asset-&gt;filename = $file['name'];
    $asset-&gt;newFolderId = $folder-&gt;id;
    $asset-&gt;volumeId = $folder-&gt;volumeId;
    $asset-&gt;avoidFilenameConflicts = true;
    $asset-&gt;setScenario(Asset::SCENARIO_CREATE);

    $result = Craft::$app-&gt;getElements()-&gt;saveElement($asset);

    // In case of error, let user know about it.
    if ($result === false) {
        throw new Exception('Error while upload asset');
    }

    return $asset-&gt;id;
}