curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/assets/import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://cdn.acme.com/catalog/shoe-red.jpg",
"file_name": "shoe-red.jpg"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/assets/import"
payload = {
"url": "https://cdn.acme.com/catalog/shoe-red.jpg",
"file_name": "shoe-red.jpg"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://cdn.acme.com/catalog/shoe-red.jpg', file_name: 'shoe-red.jpg'})
};
fetch('https://app.base44.com/api/apps/{app_id}/assets/import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/assets/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://cdn.acme.com/catalog/shoe-red.jpg',
'file_name' => 'shoe-red.jpg'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/assets/import"
payload := strings.NewReader("{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/assets/import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/assets/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}"
response = http.request(request)
puts response.read_body{
"id": "68b0e1f2a3c4d5e6f7a8b9c0",
"app_id": "6820f3a4e7b91d003c45a1f2",
"file_name": "shoe-red.jpg",
"file_url": "https://media.base44.com/images/public/6820f3a4e7b91d003c45a1f2/a1b2c3d4e_shoe-red.jpg",
"source_type": "upload",
"file_type": "jpg",
"created_date": "2026-01-15T09:23:41+00:00",
"updated_date": "2026-01-15T09:23:41+00:00"
}Import asset
Downloads a file from a public URL and stores a copy in the app’s media library, so you don’t have to download and upload it yourself. To add a file by URL without copying it, use Create asset.
The file name, from file_name or else the end of the URL’s path, decides what’s accepted, the same as Upload asset, except that svg, glb and fbx files can’t be imported: upload them instead. The copy is stored at a public URL, returned in file_url.
To retry safely, send an Idempotency-Key header. A retry with the same key and body within 24 hours returns the asset the first request added instead of importing the file again.
In this response, created_date and updated_date include a +00:00 offset. List assets returns them without one.
This endpoint is limited to 60 requests per minute, shared with Upload asset. Some workspaces have a different limit.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/assets/import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://cdn.acme.com/catalog/shoe-red.jpg",
"file_name": "shoe-red.jpg"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/assets/import"
payload = {
"url": "https://cdn.acme.com/catalog/shoe-red.jpg",
"file_name": "shoe-red.jpg"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://cdn.acme.com/catalog/shoe-red.jpg', file_name: 'shoe-red.jpg'})
};
fetch('https://app.base44.com/api/apps/{app_id}/assets/import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/assets/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://cdn.acme.com/catalog/shoe-red.jpg',
'file_name' => 'shoe-red.jpg'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/assets/import"
payload := strings.NewReader("{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/assets/import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/assets/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://cdn.acme.com/catalog/shoe-red.jpg\",\n \"file_name\": \"shoe-red.jpg\"\n}"
response = http.request(request)
puts response.read_body{
"id": "68b0e1f2a3c4d5e6f7a8b9c0",
"app_id": "6820f3a4e7b91d003c45a1f2",
"file_name": "shoe-red.jpg",
"file_url": "https://media.base44.com/images/public/6820f3a4e7b91d003c45a1f2/a1b2c3d4e_shoe-red.jpg",
"source_type": "upload",
"file_type": "jpg",
"created_date": "2026-01-15T09:23:41+00:00",
"updated_date": "2026-01-15T09:23:41+00:00"
}Authorizations
Personal access token, sent as Authorization: Bearer <token>. Each operation lists the permission it needs: read_only or full_access. A full-access token can call every operation. A read-only token can call only the operations that list read_only; anything else returns 403 read_only_credential_route_not_allowed.
Headers
One key per import. A retry with the same key and body within 24 hours returns the first asset.
1 - 128"import-shoe-red-7f3c9a"
Path Parameters
ID of the app whose media library to change.
Body
Public https URL of the file. Base44 downloads it once and stores a copy. Addresses on private networks and Base44's own hosts, other than its media CDN, are refused.
"https://cdn.acme.com/catalog/shoe-red.jpg"
Name of the file, with its extension. Defaults to the end of the URL's path. Characters other than letters, digits, _, . and - become _, anything up to the last / is dropped, and an empty name becomes untitled.
"shoe-red.jpg"
Response
The new asset.
A file in the app's media library.
ID of the asset.
"68b0e1f2a3c4d5e6f7a8b9c0"
ID of the app the asset belongs to.
"6820f3a4e7b91d003c45a1f2"
Name of the file.
"Logo-dark.png"
URL of the file.
"https://media.base44.com/files/public/6820f3a4e7b91d003c45a1f2/Logo-dark.png"
How the file got into the library. upload for a file someone uploaded, and generated for most files Base44 created for the app, such as AI-generated images and videos or a Figma import.
upload, generated "upload"
File extension without the dot, usually lowercase, such as png or mp4. The value is null when the file was added without one.
"png"
When the asset was added to the library, as a UTC timestamp in ISO 8601 format.
"2026-01-15T09:23:41"
When the asset was last changed, such as renamed, as a UTC timestamp in ISO 8601 format.
"2026-01-15T09:31:07"
Was this page helpful?