pub struct Client { /* private fields */ }Expand description
The Linear API client.
Implementations§
Source§impl Client
impl Client
Sourcepub fn from_token(token: impl Into<String>) -> Result<Self, LinearError>
pub fn from_token(token: impl Into<String>) -> Result<Self, LinearError>
Create a client with an explicit API token.
Sourcepub fn from_env() -> Result<Self, LinearError>
pub fn from_env() -> Result<Self, LinearError>
Create a client from the LINEAR_API_TOKEN environment variable.
Sourcepub fn from_token_file(path: &Path) -> Result<Self, LinearError>
pub fn from_token_file(path: &Path) -> Result<Self, LinearError>
Create a client from a token file at the given path.
Sourcepub async fn execute<T: DeserializeOwned>(
&self,
query: &str,
variables: Value,
data_path: &str,
) -> Result<T, LinearError>
pub async fn execute<T: DeserializeOwned>( &self, query: &str, variables: Value, data_path: &str, ) -> Result<T, LinearError>
Execute a GraphQL query and extract a single object from the response.
Sourcepub async fn execute_connection<T: DeserializeOwned>(
&self,
query: &str,
variables: Value,
data_path: &str,
) -> Result<Connection<T>, LinearError>
pub async fn execute_connection<T: DeserializeOwned>( &self, query: &str, variables: Value, data_path: &str, ) -> Result<Connection<T>, LinearError>
Execute a GraphQL query and extract a Connection from the response.
Sourcepub async fn query<T: DeserializeOwned + GraphQLFields>(
&self,
field: &str,
) -> Result<T, LinearError>
pub async fn query<T: DeserializeOwned + GraphQLFields>( &self, field: &str, ) -> Result<T, LinearError>
Execute a typed query using the type’s GraphQLFields implementation.
Builds the query from T::selection() — define a struct with only
the fields you need for zero-overfetch queries.
#[derive(Deserialize)]
struct MyViewer { name: Option<String>, email: Option<String> }
impl GraphQLFields for MyViewer {
fn selection() -> String { "name email".into() }
}
let me: MyViewer = client.query::<MyViewer>("viewer").await?;Sourcepub async fn query_connection<T: DeserializeOwned + GraphQLFields>(
&self,
field: &str,
) -> Result<Connection<T>, LinearError>
pub async fn query_connection<T: DeserializeOwned + GraphQLFields>( &self, field: &str, ) -> Result<Connection<T>, LinearError>
Execute a typed connection query using the node type’s
GraphQLFields implementation.
Builds { field { nodes { <T::selection()> } pageInfo { ... } } }.
Source§impl Client
impl Client
Sourcepub fn workflow_states<T>(&self) -> WorkflowStatesQueryBuilder<'_, T>
pub fn workflow_states<T>(&self) -> WorkflowStatesQueryBuilder<'_, T>
All issue workflow states (issue statuses). Returns a paginated list of workflow states visible to the authenticated user, across all teams they have access to.
Full type: WorkflowState
Sourcepub fn users<T>(&self) -> UsersQueryBuilder<'_, T>
pub fn users<T>(&self) -> UsersQueryBuilder<'_, T>
All users in the workspace. Supports filtering, sorting, and pagination.
Full type: User
Sourcepub async fn whoami<T: DeserializeOwned + GraphQLFields<FullType = User>>(
&self,
) -> Result<T, LinearError>
pub async fn whoami<T: DeserializeOwned + GraphQLFields<FullType = User>>( &self, ) -> Result<T, LinearError>
The currently authenticated user making the API request.
Full type: User
Sourcepub fn projects<T>(&self) -> ProjectsQueryBuilder<'_, T>
pub fn projects<T>(&self) -> ProjectsQueryBuilder<'_, T>
Returns all projects in the workspace, with optional filtering and sorting.
Full type: Project
Sourcepub async fn project<T: DeserializeOwned + GraphQLFields<FullType = Project>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn project<T: DeserializeOwned + GraphQLFields<FullType = Project>>( &self, id: String, ) -> Result<T, LinearError>
Returns a single project by its identifier or URL slug.
Full type: Project
Sourcepub fn teams<T>(&self) -> TeamsQueryBuilder<'_, T>
pub fn teams<T>(&self) -> TeamsQueryBuilder<'_, T>
All teams whose issues the user can access. This includes public teams and private teams the user is a member of. This may differ from administrableTeams, which returns teams whose settings the user can change but whose issues they don’t necessarily have access to.
Full type: Team
Sourcepub async fn team<T: DeserializeOwned + GraphQLFields<FullType = Team>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn team<T: DeserializeOwned + GraphQLFields<FullType = Team>>( &self, id: String, ) -> Result<T, LinearError>
Fetches a specific team by its ID.
Full type: Team
Sourcepub fn search_issues<T>(
&self,
term: impl Into<String>,
) -> SearchIssuesQueryBuilder<'_, T>
pub fn search_issues<T>( &self, term: impl Into<String>, ) -> SearchIssuesQueryBuilder<'_, T>
Search issues by text query using full-text and vector search. Results are ranked by relevance unless an orderBy parameter is specified. Supports optional issue filters and comment inclusion. Rate-limited to 30 requests per minute.
Full type: IssueSearchResult
Sourcepub fn project_statuses<T>(&self) -> ProjectStatusesQueryBuilder<'_, T>
pub fn project_statuses<T>(&self) -> ProjectStatusesQueryBuilder<'_, T>
Returns all project statuses in the workspace.
Full type: ProjectStatus
Sourcepub fn project_milestones<T>(&self) -> ProjectMilestonesQueryBuilder<'_, T>
pub fn project_milestones<T>(&self) -> ProjectMilestonesQueryBuilder<'_, T>
Returns all project milestones in the workspace, with optional filtering.
Full type: ProjectMilestone
Sourcepub async fn project_milestone<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn project_milestone<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>( &self, id: String, ) -> Result<T, LinearError>
Returns a single project milestone by its identifier.
Full type: ProjectMilestone
Sourcepub fn project_labels<T>(&self) -> ProjectLabelsQueryBuilder<'_, T>
pub fn project_labels<T>(&self) -> ProjectLabelsQueryBuilder<'_, T>
Returns all project labels in the workspace, with optional filtering.
Full type: ProjectLabel
Sourcepub fn issues<T>(&self) -> IssuesQueryBuilder<'_, T>
pub fn issues<T>(&self) -> IssuesQueryBuilder<'_, T>
All issues. Returns a paginated list of issues visible to the authenticated user. Can be filtered by various criteria including team, assignee, state, labels, project, and cycle.
Full type: Issue
Sourcepub async fn issue<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn issue<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, id: String, ) -> Result<T, LinearError>
One specific issue, looked up by its unique identifier.
Full type: Issue
Sourcepub async fn issue_vcs_branch_search<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
branch_name: String,
) -> Result<Option<T>, LinearError>
pub async fn issue_vcs_branch_search<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, branch_name: String, ) -> Result<Option<T>, LinearError>
Find issue based on the VCS branch name.
Full type: Issue
Sourcepub fn issue_relations<T>(&self) -> IssueRelationsQueryBuilder<'_, T>
pub fn issue_relations<T>(&self) -> IssueRelationsQueryBuilder<'_, T>
All issue relations. Returns a paginated list of all issue relations (blocks, blocked by, relates to, duplicates) visible to the authenticated user.
Full type: IssueRelation
Sourcepub async fn issue_relation<T: DeserializeOwned + GraphQLFields<FullType = IssueRelation>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn issue_relation<T: DeserializeOwned + GraphQLFields<FullType = IssueRelation>>( &self, id: String, ) -> Result<T, LinearError>
One specific issue relation, looked up by its unique identifier.
Full type: IssueRelation
Sourcepub fn issue_labels<T>(&self) -> IssueLabelsQueryBuilder<'_, T>
pub fn issue_labels<T>(&self) -> IssueLabelsQueryBuilder<'_, T>
All issue labels. Returns a paginated list of labels visible to the authenticated user, including both workspace-level and team-scoped labels.
Full type: IssueLabel
Sourcepub fn documents<T>(&self) -> DocumentsQueryBuilder<'_, T>
pub fn documents<T>(&self) -> DocumentsQueryBuilder<'_, T>
All documents the user has access to in the workspace.
Full type: Document
Sourcepub async fn document<T: DeserializeOwned + GraphQLFields<FullType = Document>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn document<T: DeserializeOwned + GraphQLFields<FullType = Document>>( &self, id: String, ) -> Result<T, LinearError>
A specific document by ID or slug.
Full type: Document
Sourcepub fn cycles<T>(&self) -> CyclesQueryBuilder<'_, T>
pub fn cycles<T>(&self) -> CyclesQueryBuilder<'_, T>
All cycles accessible to the user.
Full type: Cycle
Sourcepub async fn cycle<T: DeserializeOwned + GraphQLFields<FullType = Cycle>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn cycle<T: DeserializeOwned + GraphQLFields<FullType = Cycle>>( &self, id: String, ) -> Result<T, LinearError>
One specific cycle, looked up by ID or slug.
Full type: Cycle
Sourcepub async fn file_upload(
&self,
meta_data: Option<Value>,
make_public: Option<bool>,
size: i64,
content_type: String,
filename: String,
) -> Result<Value, LinearError>
pub async fn file_upload( &self, meta_data: Option<Value>, make_public: Option<bool>, size: i64, content_type: String, filename: String, ) -> Result<Value, LinearError>
XHR request payload to upload an images, video and other attachments directly to Linear’s cloud storage.
Sourcepub async fn image_upload_from_url(
&self,
url: String,
) -> Result<Value, LinearError>
pub async fn image_upload_from_url( &self, url: String, ) -> Result<Value, LinearError>
Upload an image from an URL to Linear.
Sourcepub async fn project_create<T: DeserializeOwned + GraphQLFields<FullType = Project>>(
&self,
slack_channel_name: Option<String>,
input: ProjectCreateInput,
) -> Result<T, LinearError>
pub async fn project_create<T: DeserializeOwned + GraphQLFields<FullType = Project>>( &self, slack_channel_name: Option<String>, input: ProjectCreateInput, ) -> Result<T, LinearError>
Creates a new project.
Full type: Project
Sourcepub async fn project_update<T: DeserializeOwned + GraphQLFields<FullType = Project>>(
&self,
input: ProjectUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn project_update<T: DeserializeOwned + GraphQLFields<FullType = Project>>( &self, input: ProjectUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a project.
Full type: Project
Sourcepub async fn project_delete<T: DeserializeOwned + GraphQLFields<FullType = Project>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn project_delete<T: DeserializeOwned + GraphQLFields<FullType = Project>>( &self, id: String, ) -> Result<T, LinearError>
Deletes (trashes) a project. The project can be restored later with projectUnarchive.
Full type: Project
Sourcepub async fn team_create<T: DeserializeOwned + GraphQLFields<FullType = Team>>(
&self,
copy_settings_from_team_id: Option<String>,
input: TeamCreateInput,
) -> Result<T, LinearError>
pub async fn team_create<T: DeserializeOwned + GraphQLFields<FullType = Team>>( &self, copy_settings_from_team_id: Option<String>, input: TeamCreateInput, ) -> Result<T, LinearError>
Creates a new team. The user who creates the team will automatically be added as a member and owner of the newly created team. Default workflow states, labels, and other team resources are created alongside the team.
Full type: Team
Sourcepub async fn team_update<T: DeserializeOwned + GraphQLFields<FullType = Team>>(
&self,
mapping: Option<InheritanceEntityMapping>,
input: TeamUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn team_update<T: DeserializeOwned + GraphQLFields<FullType = Team>>( &self, mapping: Option<InheritanceEntityMapping>, input: TeamUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a team’s settings, properties, or configuration. Requires team owner or workspace admin permissions for most changes.
Full type: Team
Sourcepub async fn team_delete(&self, id: String) -> Result<Value, LinearError>
pub async fn team_delete(&self, id: String) -> Result<Value, LinearError>
Archives a team and schedules its data for deletion. Requires team owner or workspace admin permissions.
Sourcepub async fn team_membership_create<T: DeserializeOwned + GraphQLFields<FullType = TeamMembership>>(
&self,
input: TeamMembershipCreateInput,
) -> Result<T, LinearError>
pub async fn team_membership_create<T: DeserializeOwned + GraphQLFields<FullType = TeamMembership>>( &self, input: TeamMembershipCreateInput, ) -> Result<T, LinearError>
Creates a new team membership, adding a user to a team. Validates that the user is not already a member, the team is not archived or retired, and the requesting user has permission to add members.
Full type: TeamMembership
Sourcepub async fn team_membership_delete(
&self,
also_leave_parent_teams: Option<bool>,
id: String,
) -> Result<Value, LinearError>
pub async fn team_membership_delete( &self, also_leave_parent_teams: Option<bool>, id: String, ) -> Result<Value, LinearError>
Deletes a team membership, removing the user from the team. Users can remove their own membership, or team owners and workspace admins can remove other members.
Sourcepub async fn project_milestone_create<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>(
&self,
input: ProjectMilestoneCreateInput,
) -> Result<T, LinearError>
pub async fn project_milestone_create<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>( &self, input: ProjectMilestoneCreateInput, ) -> Result<T, LinearError>
Creates a new project milestone.
Full type: ProjectMilestone
Sourcepub async fn project_milestone_update<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>(
&self,
input: ProjectMilestoneUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn project_milestone_update<T: DeserializeOwned + GraphQLFields<FullType = ProjectMilestone>>( &self, input: ProjectMilestoneUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a project milestone.
Full type: ProjectMilestone
Sourcepub async fn project_milestone_delete(
&self,
id: String,
) -> Result<Value, LinearError>
pub async fn project_milestone_delete( &self, id: String, ) -> Result<Value, LinearError>
Deletes a project milestone.
Sourcepub async fn issue_create<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
input: IssueCreateInput,
) -> Result<T, LinearError>
pub async fn issue_create<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, input: IssueCreateInput, ) -> Result<T, LinearError>
Creates a new issue.
Full type: Issue
Sourcepub async fn issue_update<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
input: IssueUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn issue_update<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, input: IssueUpdateInput, id: String, ) -> Result<T, LinearError>
Updates an issue.
Full type: Issue
Sourcepub async fn issue_batch_update<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
input: IssueUpdateInput,
ids: Vec<String>,
) -> Result<Vec<T>, LinearError>
pub async fn issue_batch_update<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, input: IssueUpdateInput, ids: Vec<String>, ) -> Result<Vec<T>, LinearError>
Updates multiple issues at once.
Full type: Issue
Sourcepub async fn issue_archive<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
trash: Option<bool>,
id: String,
) -> Result<T, LinearError>
pub async fn issue_archive<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, trash: Option<bool>, id: String, ) -> Result<T, LinearError>
Archives an issue.
Full type: Issue
Sourcepub async fn issue_unarchive<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn issue_unarchive<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, id: String, ) -> Result<T, LinearError>
Unarchives an issue.
Full type: Issue
Sourcepub async fn issue_delete<T: DeserializeOwned + GraphQLFields<FullType = Issue>>(
&self,
permanently_delete: Option<bool>,
id: String,
) -> Result<T, LinearError>
pub async fn issue_delete<T: DeserializeOwned + GraphQLFields<FullType = Issue>>( &self, permanently_delete: Option<bool>, id: String, ) -> Result<T, LinearError>
Deletes (trashes) an issue.
Full type: Issue
Sourcepub async fn issue_relation_create<T: DeserializeOwned + GraphQLFields<FullType = IssueRelation>>(
&self,
override_created_at: Option<Value>,
input: IssueRelationCreateInput,
) -> Result<T, LinearError>
pub async fn issue_relation_create<T: DeserializeOwned + GraphQLFields<FullType = IssueRelation>>( &self, override_created_at: Option<Value>, input: IssueRelationCreateInput, ) -> Result<T, LinearError>
Creates a new issue relation.
Full type: IssueRelation
Sourcepub async fn issue_relation_delete(
&self,
id: String,
) -> Result<Value, LinearError>
pub async fn issue_relation_delete( &self, id: String, ) -> Result<Value, LinearError>
Deletes an issue relation.
Sourcepub async fn issue_label_create<T: DeserializeOwned + GraphQLFields<FullType = IssueLabel>>(
&self,
replace_team_labels: Option<bool>,
input: IssueLabelCreateInput,
) -> Result<T, LinearError>
pub async fn issue_label_create<T: DeserializeOwned + GraphQLFields<FullType = IssueLabel>>( &self, replace_team_labels: Option<bool>, input: IssueLabelCreateInput, ) -> Result<T, LinearError>
Creates a new label.
Full type: IssueLabel
Sourcepub async fn issue_label_update<T: DeserializeOwned + GraphQLFields<FullType = IssueLabel>>(
&self,
replace_team_labels: Option<bool>,
input: IssueLabelUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn issue_label_update<T: DeserializeOwned + GraphQLFields<FullType = IssueLabel>>( &self, replace_team_labels: Option<bool>, input: IssueLabelUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a label.
Full type: IssueLabel
Sourcepub async fn issue_label_delete(&self, id: String) -> Result<Value, LinearError>
pub async fn issue_label_delete(&self, id: String) -> Result<Value, LinearError>
Deletes an issue label.
Sourcepub async fn document_create<T: DeserializeOwned + GraphQLFields<FullType = Document>>(
&self,
input: DocumentCreateInput,
) -> Result<T, LinearError>
pub async fn document_create<T: DeserializeOwned + GraphQLFields<FullType = Document>>( &self, input: DocumentCreateInput, ) -> Result<T, LinearError>
Creates a new document.
Full type: Document
Sourcepub async fn document_update<T: DeserializeOwned + GraphQLFields<FullType = Document>>(
&self,
input: DocumentUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn document_update<T: DeserializeOwned + GraphQLFields<FullType = Document>>( &self, input: DocumentUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a document.
Full type: Document
Sourcepub async fn document_delete<T: DeserializeOwned + GraphQLFields<FullType = Document>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn document_delete<T: DeserializeOwned + GraphQLFields<FullType = Document>>( &self, id: String, ) -> Result<T, LinearError>
Deletes (trashes) a document. The document is marked as trashed and archived, but not permanently removed.
Full type: Document
Sourcepub async fn comment_create<T: DeserializeOwned + GraphQLFields<FullType = Comment>>(
&self,
input: CommentCreateInput,
) -> Result<T, LinearError>
pub async fn comment_create<T: DeserializeOwned + GraphQLFields<FullType = Comment>>( &self, input: CommentCreateInput, ) -> Result<T, LinearError>
Creates a new comment.
Full type: Comment
Sourcepub async fn comment_update<T: DeserializeOwned + GraphQLFields<FullType = Comment>>(
&self,
skip_edited_at: Option<bool>,
input: CommentUpdateInput,
id: String,
) -> Result<T, LinearError>
pub async fn comment_update<T: DeserializeOwned + GraphQLFields<FullType = Comment>>( &self, skip_edited_at: Option<bool>, input: CommentUpdateInput, id: String, ) -> Result<T, LinearError>
Updates a comment.
Full type: Comment
Sourcepub async fn comment_delete(&self, id: String) -> Result<Value, LinearError>
pub async fn comment_delete(&self, id: String) -> Result<Value, LinearError>
Deletes a comment.
Sourcepub async fn comment_resolve<T: DeserializeOwned + GraphQLFields<FullType = Comment>>(
&self,
resolving_comment_id: Option<String>,
id: String,
) -> Result<T, LinearError>
pub async fn comment_resolve<T: DeserializeOwned + GraphQLFields<FullType = Comment>>( &self, resolving_comment_id: Option<String>, id: String, ) -> Result<T, LinearError>
Resolves a comment thread. Marks the root comment as resolved by the current user.
Full type: Comment
Sourcepub async fn comment_unresolve<T: DeserializeOwned + GraphQLFields<FullType = Comment>>(
&self,
id: String,
) -> Result<T, LinearError>
pub async fn comment_unresolve<T: DeserializeOwned + GraphQLFields<FullType = Comment>>( &self, id: String, ) -> Result<T, LinearError>
Unresolves a previously resolved comment thread. Clears the resolved state on the root comment.
Full type: Comment
Source§impl Client
impl Client
Sourcepub async fn download_url(
&self,
url: &str,
) -> Result<DownloadResult, LinearError>
pub async fn download_url( &self, url: &str, ) -> Result<DownloadResult, LinearError>
Download a file from a URL.
Handles Linear’s signed/expiring CDN URLs (e.g. https://uploads.linear.app/...)
as well as any other publicly accessible URL. Returns the raw bytes and
content type so the caller can write them to disk or process them further.
§Errors
Returns LinearError::HttpError if the server responds with a non-2xx status,
or LinearError::Network if the request fails at the transport level.
§Example
let client = lineark_sdk::Client::from_env()?;
let result = client.download_url("https://uploads.linear.app/...").await?;
std::fs::write("output.png", &result.bytes).unwrap();Sourcepub async fn upload_file(
&self,
filename: &str,
content_type: &str,
bytes: Vec<u8>,
make_public: bool,
) -> Result<UploadResult, LinearError>
pub async fn upload_file( &self, filename: &str, content_type: &str, bytes: Vec<u8>, make_public: bool, ) -> Result<UploadResult, LinearError>
Upload a file to Linear’s cloud storage.
This is a two-step process:
- Call the
fileUploadGraphQL mutation to obtain a signed upload URL and required headers from Linear. PUTthe raw file bytes to that signed URL (a Google Cloud Storage endpoint).
On success, returns an UploadResult containing the permanent asset_url
that can be referenced in issue descriptions, comments, or attachments.
§Arguments
filename— The original filename (e.g."screenshot.png"). Linear uses this for display and content-type inference on its side.content_type— MIME type of the file (e.g."image/png").bytes— The raw file content.make_public— Iftrue, the uploaded file will be publicly accessible without authentication.
§Errors
Returns an error if the fileUpload mutation fails, if the signed URL
upload fails, or if the response is missing expected fields.
§Example
let client = lineark_sdk::Client::from_env()?;
let bytes = std::fs::read("screenshot.png").unwrap();
let result = client
.upload_file("screenshot.png", "image/png", bytes, false)
.await?;
println!("Uploaded to: {}", result.asset_url);