Download an artifact file
September 29, 2026
Table of contents
Download the file of a completed Studio artifact. The response body is the file itself, streamed from Google on each request and never stored by us.
Google’s media URLs only open with the Google account’s cookies, so every file link in a finished job result and in GET /artifacts/artifact points here instead. Those links are ready to use: call them with your API token in the Authorization header. They keep working as long as the artifact stays in its notebook. Once the artifact is deleted they answer 404, and deleting its notebook takes them with it.
Artifact type | format | Content type |
|---|---|---|
audio | m4a | audio/mp4 |
video | mp4 | video/mp4 |
slides | pdf | application/pdf |
slides | pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
slides | slide + index | image/png, one slide image |
infographic | png | image/png |
Reports, interactive reports, data tables, quizzes, flashcards and mind maps have no file: their text, rows or JSON are in the artifact itself.
https://api.useapi.net/v1/gemini-notebook/artifacts/download?artifact=
artifact&format=format
Request Headers
Authorization: Bearer {API token}
# Optional, passed through to Google
Range: bytes=0-1048575
API tokenis required, see Setup useapi.net for details.Rangeis optional. It is forwarded to Google, so a player can seek in long audio and video or a client can resume a download. A range request answers206 Partial ContentwithContent-Range.
Query Parameters
artifactis required, the artifact id from GET /artifacts or a job. URL-encode it (it contains:and@).formatis required, which file to download.
Supported values:m4a,mp4,pdf,pptx,png,slide.
The artifact must have that file, see the table above.indexis required withformat=slideand ignored otherwise, the 1-based slide number.
Range:1to500, and at most the number of slides in the deck.
Response headers
Content-Type: the file’s type from the table above.Content-Disposition:attachment; filename="<artifact title>.<format>", for a slide image"<artifact title> slide <index>.png". The title keeps letters, digits, spaces,.,_and-, is cut to 100 characters, and falls back toartifactwhen nothing is left. Rename the artifact to change it.Content-Length,Accept-Ranges,Content-Range,ETag,Last-Modified: passed through from Google when it sends them.Cache-Control: private, no-store.
Responses
-
The raw file bytes (not JSON), for example:
Content-Type: audio/mp4 Content-Disposition: attachment; filename="Fue suerte el descenso del Eagle.m4a" Cache-Control: private, no-store -
The requested byte range of the file, when the request carried a
Rangeheader. -
A parameter is missing or invalid, or
format=slidecame withoutindex.{ "error": "index (1-based slide number) is required with format slide", "code": 400 } -
Invalid API token.
{ "error": "useapi.net ⁝ Unauthorized", "code": 401 } -
The artifact id was issued to a different API token.
{ "error": "user:[email protected]:d02c903b-…:07b94418-… does not belong to this API token", "code": 403 } -
The artifact has no file in that
format(wrong type, not completed yet, or a slideindexpast the last slide), or the artifact is gone from its notebook. The message lists the formats the artifact does have.{ "error": "No m4a file on this video (status completed); available: mp4", "code": 404 }{ "error": "Artifact user:[email protected]:d02c903b-…:07b94418-… not found", "code": 404 } -
Google did not serve the file (the message names where the fetch stopped). Retry shortly.
{ "error": "Google request failed: media fetch failed at lh3.googleusercontent.com (HTTP 403, text/html)", "code": 502 } -
596 Account Error
Google reported the account as signed out. While we re-check it, the answer is the first message below. Retry in about a minute. If it stays signed out, the account is paused, you receive an email, and the answer becomes the second message until you re-add it via Setup Gemini Notebook.
{ "error": "Google reported this account as signed out. We are re-checking it — please retry in about a minute. If it stays signed out, you will receive a re-add email.", "code": 596 }{ "error": "Account [email protected]: Google signed this account out. Re-add it at https://useapi.net/docs/start-here/setup-gemini-notebook", "code": 596 }
Model
A successful response is the file itself (not JSON), with the headers listed above. Errors return:
{ // TypeScript, all fields are optional
error: string
code: number
}
Examples
-
ARTIFACT="user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:ae28f2a1-678b-4304-9806-09648fcb77a0" # The whole deck as PDF, saved under the filename from Content-Disposition curl -G -OJ "https://api.useapi.net/v1/gemini-notebook/artifacts/download" \ -H "Authorization: Bearer …" \ --data-urlencode "artifact=$ARTIFACT" \ --data-urlencode "format=pdf" # Slide 3 as PNG curl -G "https://api.useapi.net/v1/gemini-notebook/artifacts/download" \ -H "Authorization: Bearer …" \ --data-urlencode "artifact=$ARTIFACT" \ --data-urlencode "format=slide" \ --data-urlencode "index=3" \ --output slide-3.png -
const token = "API token"; const artifact = "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:0c2ba8dc-47dd-474f-a19c-c06896e269fd"; const apiUrl = `https://api.useapi.net/v1/gemini-notebook/artifacts/download?artifact=${encodeURIComponent(artifact)}&format=m4a`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); if (!response.ok) console.log("error", response.status, await response.json()); else { const audio = await response.arrayBuffer(); console.log("downloaded", audio.byteLength, response.headers.get("content-disposition")); } -
import requests token = "API token" artifact = "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:0449d123-6d1e-4864-ab28-ecac88a74c53" apiUrl = "https://api.useapi.net/v1/gemini-notebook/artifacts/download" headers = { "Authorization" : f"Bearer {token}" } with requests.get(apiUrl, headers=headers, params={"artifact": artifact, "format": "mp4"}, stream=True) as response: response.raise_for_status() with open("video.mp4", "wb") as f: for chunk in response.iter_content(chunk_size=1 << 20): f.write(chunk)
Try It
The form fetches the file with your token and shows audio, video and images inline. A pdf or pptx shows as <binary data>, so use the examples above to save those.