Retrieve a job
September 29, 2026
Table of contents
Fetch a job record by its jobid. Every Studio generation is a job: POST /artifacts, POST /artifacts/retry and POST /artifacts/revise all return one. So does a research run from POST /research. Poll this endpoint until status is completed or failed.
The API advances every running job about every 15 seconds, so polling more often than that gains nothing. Generation takes from under a minute (flashcards, mind maps) to 10 minutes and more (video). A job still running after 40 minutes is failed with error code timeout and its slot is freed. Google may still finish the artifact in the notebook, and GET /artifacts/artifact shows it when it does.
Instead of polling, pass replyUrl (and optionally replyRef) with the POST: when the job completes or fails, the API sends one POST of this same job record, as JSON, to that URL. See Model.
Job records are kept for 30 days.
https://api.useapi.net/v1/gemini-notebook/jobs/
jobid
jobidis URL-encoded in the path (it contains:and@), for examplejob%3A12597f9a-010c-4758-8e9a-b5cc17b0ccdb-user%3A12345-user%40example.com-bot%3Agemini_notebook.
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Responses
-
Completed (an audio overview):
{ "jobid": "job:12597f9a-010c-4758-8e9a-b5cc17b0ccdb-user:[email protected]:gemini_notebook", "email": "[email protected]", "type": "audio", "status": "completed", "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "artifact": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:0c2ba8dc-47dd-474f-a19c-c06896e269fd", "created_at": "2026-09-27T23:38:15.692Z", "request": { "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "type": "audio", "format": "debate", "length": "short", "language": "es", "instructions": "Focus on the risks the crew took during the landing." }, "completed_at": "2026-09-27T23:43:41.173Z", "result": { "title": "¿Fue suerte el descenso del Eagle?", "duration": 277, "files": [ { "format": "m4a", "mimeType": "audio/mp4", "url": "https://api.useapi.net/v1/gemini-notebook/artifacts/download?artifact=user%3A12345-user%40example.com-artifact%3Ad02c903b-17f8-4241-a263-2be9e7359d55%3A0c2ba8dc-47dd-474f-a19c-c06896e269fd&format=m4a" } ] } }Running (a cinematic video):
{ "jobid": "job:21ade7e0-f2c0-48a1-904d-688096a3ff29-user:[email protected]:gemini_notebook", "email": "[email protected]", "type": "video", "status": "processing", "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "artifact": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:7f923bb5-fb59-4ee6-ade6-9ae559a660fe", "created_at": "2026-09-28T04:32:44.630Z", "request": { "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "type": "video", "format": "cinematic" } }Completed (a research job, Discover sources, list shortened):
{ "jobid": "job:526bc256-d897-493a-9ebc-7c9f35ca4428-user:[email protected]:gemini_notebook", "email": "[email protected]", "type": "research", "status": "completed", "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "created_at": "2026-09-29T04:10:07.338Z", "request": { "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "query": "Apollo 11 lunar module guidance computer alarms", "type": "fast" }, "completed_at": "2026-09-29T04:10:23.751Z", "result": { "mode": "fast", "query": "Apollo 11 lunar module guidance computer alarms", "summary": "Navigate the technical causes, software design, and human decisions behind the famous Apollo 11 guidance computer alarms.", "sources": [ { "url": "https://www.ibiblio.org/apollo/Documents/CherryApollo11Exegesis.pdf", "title": "Exegesis of the 1201 and 1202 Alarms Which Occurred During the Mission G Lunar Landing - Ibiblio", "description": "Technical exegesis explaining the exact mechanism of 1201/1202 alarms.", "cited": true } ] } }Failed (cancelled with DELETE /jobs/
jobid):{ "jobid": "job:09112e70-e1f3-422d-a1af-955de87508e4-user:[email protected]:gemini_notebook", "email": "[email protected]", "type": "flashcards", "status": "failed", "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "artifact": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:064463cc-e0a3-4feb-9196-2cec98b55039", "created_at": "2026-09-28T03:23:42.051Z", "request": { "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "type": "flashcards", "quantity": "fewer" }, "completed_at": "2026-09-28T03:23:42.561Z", "error": { "code": "cancelled", "message": "Cancelled: the slot is freed. Google may still finish the artifact in the notebook." } } -
The path value is not a Gemini Notebook jobid.
{ "error": "Path parameter jobid (…) is not a valid jobid", "code": 400 } -
Invalid API token.
{ "error": "useapi.net ⁝ Unauthorized", "code": 401 } -
{ "error": "jobid does not belong to this API token", "code": 403 } -
No such job, or its record is older than 30 days.
{ "error": "Job job:12597f9a-…-bot:gemini_notebook not found", "code": 404 }
Model
The job record. POST /artifacts, POST /artifacts/retry, POST /artifacts/revise and POST /research return it too, and it is the body of the replyUrl webhook.
{ // TypeScript, all fields are optional
jobid: string // job:<uuid>-user:<id>-<email>-bot:gemini_notebook
email: string // the account the job runs on
type: 'audio' | 'video' | 'report' | 'interactive_report' | 'table' | 'quiz' | 'flashcards' | 'infographic' | 'slides' | 'mindmap' | 'research'
status: 'pending' | 'processing' | 'completed' | 'failed'
notebook: string // notebook id; for a one-shot, the notebook created for it
artifact?: string // artifact id, once Google has created it (never on a research job)
created_at: string // ISO 8601, when the job was accepted
updated_at?: string // one-shot only: when its artifact was created
completed_at?: string // ISO 8601, when the job completed or failed
request: Record<string, unknown> // your request body echoed back (ids as strings), without mode, replyUrl and replyRef
replyUrl?: string
replyRef?: string
warnings?: string[] // one-shot only: sources Google could not process and that were left out
error?: { // status 'failed'
code: 'quota' | 'account' | 'not_found' | 'sources' | 'generation_failed' | 'timeout' | 'google_error' | 'scheduler' | 'cancelled'
message: string
retryAt?: string // code 'quota', when Google names the window: ISO 8601 time it resets
}
result?: { // status 'completed', a Studio artifact
title: string
duration?: number // audio, video: seconds
files?: Array<{ // audio, video, infographic, slides
format: 'm4a' | 'mp4' | 'png' | 'pdf' | 'pptx'
mimeType: string
url: string // GET /artifacts/download link, needs your API token
width?: number // infographic
height?: number
}>
slides?: Array<{ // slides
image: string // GET /artifacts/download link (format=slide&index=N)
caption: string | null
text: string | null
}>
text?: string // report (Markdown), interactive_report, infographic
table?: string[][] // table: rows of cells, header row first
content?: unknown // quiz, flashcards, mindmap: Google's JSON
} | { // status 'completed', type 'research' (POST /research)
mode: 'fast' | 'deep'
query: string
summary?: string // fast: Google's one-line summary of what it found
report?: { // deep: the Deep Research report
title: string
markdown: string
}
noResults?: true // the run found nothing (sources is [])
sources: Array<{
url: string
title: string
description: string | null
cited: boolean // deep: the report cites it. fast: always true
}>
}
}
For a Studio job, result has exactly the per-type shape of a completed artifact, described on GET /artifacts/artifact. Every file url points at GET /artifacts/download, which needs your API token. For a research job (type: research), result lists what the run found, described on POST /research. Add it to the notebook with POST /research/import.
While a job runs, status keeps the value it had when the job was accepted (pending, or processing when Google had already started) and changes only when the job completes or fails. A one-shot job starts pending while its sources are processed, and its artifact appears here once Google has created it. The 202 of a sync one-shot request can already show processing once its artifact exists, while this endpoint keeps showing pending until the job completes or fails.
error.code | Meaning |
|---|---|
quota | Not enough of Google’s 5-hour or weekly usage window was left for this job. retryAt says when it resets, when Google’s refusal names the window. GET /accounts/email shows what each action needs. |
generation_failed | Google reported the generation as failed. POST /artifacts/retry re-runs it in place. For a research job, Google ended the run in a state the API does not recognise. |
sources | One-shot only: the notebook got no usable source, or its sources were still processing after 5 minutes. |
not_found | The artifact, research run or notebook disappeared while the job ran (deleted here or in the web app). |
account | Google signed the account out, and it must be re-added via Setup Gemini Notebook. The same code is used when the account was removed with DELETE /accounts/email while the job ran, with the message Account <email> is no longer configured. |
timeout | Still running after 40 minutes. Check GET /artifacts/artifact later, Google may still finish it. For a research job, check the notebook in the Gemini Notebook web app. |
cancelled | Cancelled with DELETE /jobs/jobid. A research run cancelled in the Gemini Notebook web app fails with this code too. |
scheduler | The job could not be scheduled on our side. Google may already have started the generation, so check GET /artifacts before you submit it again. |
google_error | Any other refusal from Google. message has the details. |
The replyUrl webhook is one POST with Content-Type: application/json and this record as the body, sent once when the job completes or fails (a 10-second timeout, no retries). A job cancelled with DELETE /jobs/jobid sends no webhook. Use replyRef to match the callback to your own records.
Examples
-
JOBID="job:12597f9a-010c-4758-8e9a-b5cc17b0ccdb-user:[email protected]:gemini_notebook" curl -H "Authorization: Bearer …" \ "https://api.useapi.net/v1/gemini-notebook/jobs/$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$JOBID")" -
const token = "API token"; const jobid = "job:12597f9a-010c-4758-8e9a-b5cc17b0ccdb-user:[email protected]:gemini_notebook"; const apiUrl = `https://api.useapi.net/v1/gemini-notebook/jobs/${encodeURIComponent(jobid)}`; let job; do { await new Promise(resolve => setTimeout(resolve, 15000)); const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); job = await response.json(); console.log(job.status); } while (job.status === "pending" || job.status === "processing"); console.log("job", job); -
import requests, time, urllib.parse token = "API token" jobid = "job:12597f9a-010c-4758-8e9a-b5cc17b0ccdb-user:[email protected]:gemini_notebook" apiUrl = "https://api.useapi.net/v1/gemini-notebook/jobs/" + urllib.parse.quote(jobid, safe="") headers = { "Authorization" : f"Bearer {token}" } while True: time.sleep(15) job = requests.get(apiUrl, headers=headers).json() print(job.get("status")) if job.get("status") not in ("pending", "processing"): break print(job)