diff --git a/Cargo.lock b/Cargo.lock
index 978e0ae..3f60a23 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1293,7 +1293,7 @@ dependencies = [
 
 [[package]]
 name = "rbx_asset"
-version = "0.3.4"
+version = "0.4.2"
 dependencies = [
  "chrono",
  "flate2",
diff --git a/rbx_asset/Cargo.toml b/rbx_asset/Cargo.toml
index 42ee64b..e652476 100644
--- a/rbx_asset/Cargo.toml
+++ b/rbx_asset/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rbx_asset"
-version = "0.3.4"
+version = "0.4.2"
 edition = "2021"
 publish = ["strafesnet"]
 repository = "https://git.itzana.me/StrafesNET/asset-tool"
diff --git a/rbx_asset/src/cloud.rs b/rbx_asset/src/cloud.rs
index e94c1aa..f65c7aa 100644
--- a/rbx_asset/src/cloud.rs
+++ b/rbx_asset/src/cloud.rs
@@ -1,4 +1,4 @@
-use crate::ResponseError;
+use crate::{ResponseError,ReaderType,maybe_gzip_decode,read_readable};
 
 #[derive(Debug,serde::Deserialize,serde::Serialize)]
 #[allow(nonstandard_style,dead_code)]
@@ -31,7 +31,7 @@ pub struct AssetOperation{
 	operation:RobloxOperation,
 }
 impl AssetOperation{
-	pub async fn try_get_asset(&self,context:&CloudContext)->Result<AssetResponse,AssetOperationError>{
+	pub async fn try_get_asset(&self,context:&Context)->Result<AssetResponse,AssetOperationError>{
 		serde_json::from_value(
 			self.operation
 				.try_get_reponse(context).await
@@ -119,7 +119,7 @@ impl std::error::Error for UpdateError{}
 struct GetAssetOperationRequest{
 	operation_id:String,
 }
-pub struct GetAssetInfoRequest{
+pub struct GetAssetLatestRequest{
 	pub asset_id:u64,
 }
 /*
@@ -149,25 +149,21 @@ pub struct AssetResponse{
 	pub assetId:String,//u64 wrapped in quotes wohoo!!
 	pub assetType:AssetType,
 	pub creationContext:CreationContext,
-	pub description:String,
+	pub description:Option<String>,
 	pub displayName:String,
 	pub path:String,
 	pub revisionCreateTime:chrono::DateTime<chrono::Utc>,
 	pub revisionId:String,//u64
 	pub moderationResult:ModerationResult,
 	pub icon:Option<String>,
-	pub previews:Option<Vec<Preview>>,
+	#[serde(default)]
+	pub previews:Vec<Preview>,
 }
 #[allow(nonstandard_style,dead_code)]
 pub struct GetAssetVersionRequest{
 	pub asset_id:u64,
 	pub version:u64,
 }
-#[allow(nonstandard_style,dead_code)]
-pub struct GetAssetRequest{
-	pub asset_id:u64,
-	pub version:Option<u64>,
-}
 #[derive(Debug)]
 pub enum GetError{
 	ParseError(url::ParseError),
@@ -182,6 +178,23 @@ impl std::fmt::Display for GetError{
 }
 impl std::error::Error for GetError{}
 
+#[derive(Debug,serde::Deserialize)]
+#[allow(nonstandard_style,dead_code)]
+pub struct AssetLocation{
+	// this field is private so users cannot mutate it
+	location:String,
+	pub requestId:String,
+	pub IsHashDynamic:bool,
+	pub IsCopyrightProtected:bool,
+	pub isArchived:bool,
+	pub assetTypeId:u32,
+}
+impl AssetLocation{
+	pub fn location(&self)->&str{
+		&self.location
+	}
+}
+
 pub struct AssetVersionsRequest{
 	pub asset_id:u64,
 	pub cursor:Option<String>,
@@ -286,7 +299,7 @@ impl RobloxOperation{
 			None=>self.path.as_deref()?.get(11..),
 		}
 	}
-	pub async fn try_get_reponse(&self,context:&CloudContext)->Result<serde_json::Value,OperationError>{
+	pub async fn try_get_reponse(&self,context:&Context)->Result<serde_json::Value,OperationError>{
 		context.get_asset_operation(GetAssetOperationRequest{
 			operation_id:self.operation_id()
 				.ok_or(OperationError::NoOperationId)?
@@ -296,25 +309,6 @@ impl RobloxOperation{
 	}
 }
 
-//idk how to do this better
-enum ReaderType<R:std::io::Read>{
-	GZip(flate2::read::GzDecoder<std::io::BufReader<R>>),
-	Raw(std::io::BufReader<R>),
-}
-fn maybe_gzip_decode<R:std::io::Read>(input:R)->std::io::Result<ReaderType<R>>{
-	let mut buf=std::io::BufReader::new(input);
-	let peek=std::io::BufRead::fill_buf(&mut buf)?;
-	match &peek[0..2]{
-		b"\x1f\x8b"=>Ok(ReaderType::GZip(flate2::read::GzDecoder::new(buf))),
-		_=>Ok(ReaderType::Raw(buf)),
-	}
-}
-fn read_readable(mut readable:impl std::io::Read)->std::io::Result<Vec<u8>>{
-	let mut contents=Vec::new();
-	readable.read_to_end(&mut contents)?;
-	Ok(contents)
-}
-
 #[derive(Clone)]
 pub struct ApiKey(String);
 impl ApiKey{
@@ -327,12 +321,12 @@ impl ApiKey{
 }
 
 #[derive(Clone)]
-pub struct CloudContext{
-	pub api_key:String,
-	pub client:reqwest::Client,
+pub struct Context{
+	api_key:String,
+	client:reqwest::Client,
 }
 
-impl CloudContext{
+impl Context{
 	pub fn new(api_key:ApiKey)->Self{
 		Self{
 			api_key:api_key.get(),
@@ -412,7 +406,7 @@ impl CloudContext{
 		).await.map_err(GetError::Response)?
 		.json::<RobloxOperation>().await.map_err(GetError::Reqwest)
 	}
-	pub async fn get_asset_info(&self,config:GetAssetInfoRequest)->Result<AssetResponse,GetError>{
+	pub async fn get_asset_info(&self,config:GetAssetLatestRequest)->Result<AssetResponse,GetError>{
 		let raw_url=format!("https://apis.roblox.com/assets/v1/assets/{}",config.asset_id);
 		let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
 
@@ -421,31 +415,47 @@ impl CloudContext{
 		).await.map_err(GetError::Response)?
 		.json::<AssetResponse>().await.map_err(GetError::Reqwest)
 	}
-	pub async fn get_asset_version(&self,config:GetAssetVersionRequest)->Result<Vec<u8>,GetError>{
+	pub async fn get_asset_version_info(&self,config:GetAssetVersionRequest)->Result<AssetResponse,GetError>{
 		let raw_url=format!("https://apis.roblox.com/assets/v1/assets/{}/versions/{}",config.asset_id,config.version);
 		let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
 
+		crate::response_ok(
+			self.get(url).await.map_err(GetError::Reqwest)?
+		).await.map_err(GetError::Response)?
+		.json::<AssetResponse>().await.map_err(GetError::Reqwest)
+	}
+	pub async fn get_asset_location(&self,config:GetAssetLatestRequest)->Result<AssetLocation,GetError>{
+		let raw_url=format!("https://apis.roblox.com/asset-delivery-api/v1/assetId/{}",config.asset_id);
+		let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
+
+		crate::response_ok(
+			self.get(url).await.map_err(GetError::Reqwest)?
+		).await.map_err(GetError::Response)?
+		.json().await.map_err(GetError::Reqwest)
+	}
+	pub async fn get_asset_version_location(&self,config:GetAssetVersionRequest)->Result<AssetLocation,GetError>{
+		let raw_url=format!("https://apis.roblox.com/asset-delivery-api/v1/assetId/{}/version/{}",config.asset_id,config.version);
+		let url=reqwest::Url::parse(raw_url.as_str()).map_err(GetError::ParseError)?;
+
+		crate::response_ok(
+			self.get(url).await.map_err(GetError::Reqwest)?
+		).await.map_err(GetError::Response)?
+		.json().await.map_err(GetError::Reqwest)
+	}
+	pub async fn get_asset(&self,config:&AssetLocation)->Result<Vec<u8>,GetError>{
+		let url=reqwest::Url::parse(config.location.as_str()).map_err(GetError::ParseError)?;
+
 		let body=crate::response_ok(
 			self.get(url).await.map_err(GetError::Reqwest)?
 		).await.map_err(GetError::Response)?
 		.bytes().await.map_err(GetError::Reqwest)?;
 
-		match maybe_gzip_decode(&mut std::io::Cursor::new(body)){
+		match maybe_gzip_decode(std::io::Cursor::new(body)){
 			Ok(ReaderType::GZip(readable))=>read_readable(readable),
 			Ok(ReaderType::Raw(readable))=>read_readable(readable),
 			Err(e)=>Err(e),
 		}.map_err(GetError::IO)
 	}
-	pub async fn get_asset(&self,config:GetAssetRequest)->Result<Vec<u8>,GetError>{
-		let version=match config.version{
-			Some(version)=>version,
-			None=>self.get_asset_info(GetAssetInfoRequest{asset_id:config.asset_id}).await?.revisionId.parse().unwrap(),
-		};
-		self.get_asset_version(GetAssetVersionRequest{
-			asset_id:config.asset_id,
-			version,
-		}).await
-	}
 	pub async fn get_asset_versions(&self,config:AssetVersionsRequest)->Result<AssetVersionsResponse,AssetVersionsError>{
 		let raw_url=format!("https://apis.roblox.com/assets/v1/assets/{}/versions",config.asset_id);
 		let url=reqwest::Url::parse(raw_url.as_str()).map_err(AssetVersionsError::ParseError)?;
diff --git a/rbx_asset/src/cookie.rs b/rbx_asset/src/cookie.rs
index f09223d..7ad53f2 100644
--- a/rbx_asset/src/cookie.rs
+++ b/rbx_asset/src/cookie.rs
@@ -1,4 +1,4 @@
-use crate::ResponseError;
+use crate::{ResponseError,ReaderType,maybe_gzip_decode,read_readable};
 
 #[derive(Debug)]
 pub enum PostError{
@@ -306,25 +306,6 @@ pub struct UserInventoryPageResponse{
 	pub data:Vec<UserInventoryItem>,
 }
 
-//idk how to do this better
-enum ReaderType<R:std::io::Read>{
-	GZip(flate2::read::GzDecoder<std::io::BufReader<R>>),
-	Raw(std::io::BufReader<R>),
-}
-fn maybe_gzip_decode<R:std::io::Read>(input:R)->std::io::Result<ReaderType<R>>{
-	let mut buf=std::io::BufReader::new(input);
-	let peek=std::io::BufRead::fill_buf(&mut buf)?;
-	match &peek[0..2]{
-		b"\x1f\x8b"=>Ok(ReaderType::GZip(flate2::read::GzDecoder::new(buf))),
-		_=>Ok(ReaderType::Raw(buf)),
-	}
-}
-fn read_readable(mut readable:impl std::io::Read)->std::io::Result<Vec<u8>>{
-	let mut contents=Vec::new();
-	readable.read_to_end(&mut contents)?;
-	Ok(contents)
-}
-
 #[derive(Clone)]
 pub struct Cookie(String);
 impl Cookie{
@@ -337,12 +318,12 @@ impl Cookie{
 	}
 }
 #[derive(Clone)]
-pub struct CookieContext{
-	pub cookie:String,
-	pub client:reqwest::Client,
+pub struct Context{
+	cookie:String,
+	client:reqwest::Client,
 }
 
-impl CookieContext{
+impl Context{
 	pub fn new(cookie:Cookie)->Self{
 		Self{
 			cookie:cookie.get(),
diff --git a/rbx_asset/src/lib.rs b/rbx_asset/src/lib.rs
index 7728978..c41ff74 100644
--- a/rbx_asset/src/lib.rs
+++ b/rbx_asset/src/lib.rs
@@ -20,7 +20,7 @@ impl std::fmt::Display for ResponseError{
 }
 impl std::error::Error for ResponseError{}
 // lazy function to draw out meaningful info from http response on failure
-pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,ResponseError>{
+pub(crate) async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,ResponseError>{
 	let status_code=response.status();
 	if status_code.is_success(){
 		Ok(response)
@@ -35,3 +35,22 @@ pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,R
 		}))
 	}
 }
+
+//idk how to do this better
+pub(crate) enum ReaderType<R:std::io::Read>{
+	GZip(flate2::read::GzDecoder<std::io::BufReader<R>>),
+	Raw(std::io::BufReader<R>),
+}
+pub(crate) fn maybe_gzip_decode<R:std::io::Read>(input:R)->std::io::Result<ReaderType<R>>{
+	let mut buf=std::io::BufReader::new(input);
+	let peek=std::io::BufRead::fill_buf(&mut buf)?;
+	match &peek[0..2]{
+		b"\x1f\x8b"=>Ok(ReaderType::GZip(flate2::read::GzDecoder::new(buf))),
+		_=>Ok(ReaderType::Raw(buf)),
+	}
+}
+pub(crate) fn read_readable(mut readable:impl std::io::Read)->std::io::Result<Vec<u8>>{
+	let mut contents=Vec::new();
+	readable.read_to_end(&mut contents)?;
+	Ok(contents)
+}
diff --git a/src/main.rs b/src/main.rs
index 9d4c79b..ba89009 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,8 +2,8 @@ use std::{io::Read,path::PathBuf};
 use clap::{Args,Parser,Subcommand};
 use anyhow::{anyhow,Result as AResult};
 use futures::StreamExt;
-use rbx_asset::cloud::{ApiKey,CloudContext};
-use rbx_asset::cookie::{Cookie,CookieContext,AssetVersion,CreationsItem};
+use rbx_asset::cloud::{ApiKey,Context as CloudContext};
+use rbx_asset::cookie::{Cookie,Context as CookieContext,AssetVersion,CreationsItem};
 
 type AssetID=u64;
 type AssetIDFileMap=Vec<(AssetID,PathBuf)>;