Skip to main content
The Assets resource provides methods to manage application binaries, configuration files, and other assets that can be used with iOS and Android instances.

Methods

getOrCreate()

Creates an asset and returns upload and download URLs. If there is a corresponding file uploaded in the storage with the given name, its MD5 is returned so you can check if a re-upload is necessary.
getOrCreate(
  body: AssetGetOrCreateParams,
  options?: RequestOptions
): APIPromise<AssetGetOrCreateResponse>

Parameters

name
string
required
The unique name for the asset. This will be used to reference the asset when creating instances.

Returns

id
string
required
Unique identifier for the asset.
name
string
required
The name of the asset.
signedUploadUrl
string
required
Pre-signed URL for uploading the asset file. Use this URL to PUT your file content.
signedDownloadUrl
string
required
Pre-signed URL for downloading the asset file.
md5
string
MD5 hash of the file. Returned only if there is a corresponding file uploaded already. If this is not present, you must upload the file using the signedUploadUrl before the asset can be used.

Example

// Create or get an asset
const asset = await limrun.assets.getOrCreate({
  name: "my-app-v1.2.3.apk"
});

if (!asset.md5) {
  // File doesn't exist yet, upload it
  const fileBuffer = await fs.readFile("./my-app-v1.2.3.apk");
  
  await fetch(asset.signedUploadUrl, {
    method: "PUT",
    body: fileBuffer,
    headers: {
      "Content-Type": "application/vnd.android.package-archive"
    }
  });
  
  console.log("Asset uploaded successfully");
} else {
  console.log("Asset already exists with MD5:", asset.md5);
}

// Use the asset when creating an instance
const instance = await limrun.androidInstances.create({
  spec: {
    initialAssets: [
      {
        kind: "App",
        source: "AssetName",
        assetName: "my-app-v1.2.3.apk"
      }
    ]
  }
});

getOrUpload()

Simplified method that combines getOrCreate with automatic file upload. This method reads the file from disk, computes its MD5, and only uploads if the file doesn’t already exist or has changed.
getOrUpload(
  body: AssetGetOrUploadParams,
  options?: RequestOptions
): Promise<AssetGetOrUploadResponse>

Parameters

path
string
required
The path to the file to upload.
name
string
The name for the asset. Defaults to the basename of the file path.

Returns

id
string
required
Unique identifier for the asset.
name
string
required
The name of the asset.
signedDownloadUrl
string
required
Pre-signed URL for downloading the asset file.
md5
string
required
MD5 hash of the uploaded file.

Example

// Upload a file - automatically handles MD5 checking and upload
const asset = await limrun.assets.getOrUpload({
  path: "./my-app-v1.2.3.apk"
});

console.log("Asset ready:", asset.signedDownloadUrl);
console.log("MD5:", asset.md5);

// Use with custom name
const renamedAsset = await limrun.assets.getOrUpload({
  path: "./build/app.apk",
  name: "my-app-v1.2.3.apk"
});
This method is more convenient than getOrCreate because it automatically computes the MD5 hash and handles the upload process. It will skip the upload if an asset with the same name and MD5 already exists.

list()

List organization’s assets with optional filters.
list(
  query?: AssetListParams,
  options?: RequestOptions
): APIPromise<AssetListResponse>

Parameters

nameFilter
string
Query by file name. Supports partial matching.
includeAppStore
boolean
If true, also includes assets from Limrun App Store where you have access to. App Store assets will be returned with a "appstore/" prefix in their names.
includeDownloadUrl
boolean
Toggles whether a download URL should be included in the response.
includeUploadUrl
boolean
Toggles whether an upload URL should be included in the response.
limit
number
Maximum number of items to be returned. The default is 50.

Returns

Returns an array of Asset objects.
Asset[]
array
required
id
string
required
Unique identifier for the asset.
name
string
required
The name of the asset.
displayName
string
Human-readable display name for the asset. If not set, the name should be used.
os
string
The operating system this asset is for: "ios" or "android". If not set, the asset is available for all platforms.
md5
string
MD5 hash of the file. Returned only if there is a corresponding file uploaded already.
signedDownloadUrl
string
Pre-signed URL for downloading the asset. Only included if includeDownloadUrl is true.
signedUploadUrl
string
Pre-signed URL for uploading the asset. Only included if includeUploadUrl is true.

Example

// List all assets
const assets = await limrun.assets.list();

for (const asset of assets) {
  console.log(`${asset.name} (${asset.os || 'all platforms'})`);
}

// List Android APKs with download URLs
const androidAssets = await limrun.assets.list({
  nameFilter: ".apk",
  includeDownloadUrl: true,
  limit: 100
});

// List assets including App Store items
const allAssets = await limrun.assets.list({
  includeAppStore: true
});

get()

Get a specific asset by ID.
get(
  assetID: string,
  query?: AssetGetParams,
  options?: RequestOptions
): APIPromise<Asset>

Parameters

assetID
string
required
The unique identifier of the asset.
includeDownloadUrl
boolean
Toggles whether a download URL should be included in the response.
includeUploadUrl
boolean
Toggles whether an upload URL should be included in the response.

Returns

Returns an Asset object with the same structure as described in the list() method.

Example

// Get asset with download URL
const asset = await limrun.assets.get("asset_123", {
  includeDownloadUrl: true
});

console.log(asset.name);
console.log(asset.md5);

if (asset.signedDownloadUrl) {
  // Download the asset
  const response = await fetch(asset.signedDownloadUrl);
  const buffer = await response.arrayBuffer();
  await fs.writeFile(`./downloads/${asset.name}`, Buffer.from(buffer));
}

delete()

Delete an asset by ID.
delete(
  assetID: string,
  options?: RequestOptions
): APIPromise<void>

Parameters

assetID
string
required
The unique identifier of the asset to delete.

Returns

Returns a promise that resolves when the asset is deleted.

Example

await limrun.assets.delete("asset_123");
console.log("Asset deleted successfully");

Type Definitions

Asset

The complete asset object returned by the API.
interface Asset {
  id: string;
  name: string;
  displayName?: string;
  os?: 'ios' | 'android';
  md5?: string;
  signedDownloadUrl?: string;
  signedUploadUrl?: string;
}

AssetListResponse

Response from listing assets.
type AssetListResponse = Array<Asset>;

AssetGetOrCreateResponse

Response from creating or retrieving an asset.
interface AssetGetOrCreateResponse {
  id: string;
  name: string;
  signedDownloadUrl: string;
  signedUploadUrl: string;
  md5?: string;
}

AssetGetOrCreateParams

Parameters for creating or retrieving an asset.
interface AssetGetOrCreateParams {
  name: string;
}

AssetListParams

Parameters for listing assets.
interface AssetListParams {
  nameFilter?: string;
  includeAppStore?: boolean;
  includeDownloadUrl?: boolean;
  includeUploadUrl?: boolean;
  limit?: number;
}

AssetGetParams

Parameters for retrieving a single asset.
interface AssetGetParams {
  includeDownloadUrl?: boolean;
  includeUploadUrl?: boolean;
}

Usage Patterns

Uploading a New Asset

// Step 1: Create or get the asset
const asset = await limrun.assets.getOrCreate({
  name: "my-ios-app.ipa"
});

// Step 2: Check if upload is needed
if (!asset.md5) {
  // Step 3: Upload the file
  const fileBuffer = await fs.readFile("./build/my-ios-app.ipa");
  
  const uploadResponse = await fetch(asset.signedUploadUrl, {
    method: "PUT",
    body: fileBuffer,
    headers: {
      "Content-Type": "application/octet-stream"
    }
  });
  
  if (!uploadResponse.ok) {
    throw new Error("Failed to upload asset");
  }
  
  console.log("Asset uploaded:", asset.id);
} else {
  console.log("Asset already exists, skipping upload");
}

Using Assets with Instances

// Create an Android instance with multiple assets
const instance = await limrun.androidInstances.create({
  wait: true,
  spec: {
    initialAssets: [
      {
        kind: "App",
        source: "AssetName",
        assetName: "my-app.apk"
      },
      {
        kind: "Configuration",
        source: "AssetName",
        assetName: "test-config.json"
      }
    ]
  }
});

Downloading an Asset

// Get asset with download URL
const asset = await limrun.assets.get("asset_123", {
  includeDownloadUrl: true
});

if (asset.signedDownloadUrl) {
  const response = await fetch(asset.signedDownloadUrl);
  const arrayBuffer = await response.arrayBuffer();
  await fs.writeFile(`./downloads/${asset.name}`, Buffer.from(arrayBuffer));
  console.log(`Downloaded ${asset.name}`);
}

Build docs developers (and LLMs) love