Import research results
September 29, 2026
Table of contents
Add the results of a completed POST /research job to the notebook it ran on, the Import button of the Gemini Notebook web app. Web pages are added as web sources (Google may type a PDF link as pdf), YouTube links as YouTube sources, Google Drive results (source: "drive") as Drive sources (a Google Doc as google_docs, which you can keep in sync with POST /sources/sync, other files as drive), and a Deep Research report as a Markdown source titled after the report.
A Drive result whose mimeType is null cannot be imported: the API answers 400 before Google is called. Leave its URL out of urls and add the file with POST /sources and drive: [{ fileId, mimeType, name }].
What gets imported:
- Without
urls, the same as the web app’s Import: the report (Deep Research only) plus every source the result markscited. For Discover sources (fast) that is every source. Sendreport: falseto leave the report out. - With
urls, only those sources. Each URL must appear in the job’sresult.sources, cited or not. The report is added only withreport: true.urls: []withreport: trueimports only the report.
Google fetches every URL before it answers, so an import usually answers within one to two minutes (55 seconds to 2 minutes in our tests). If Google takes longer, the API answers 504 after about two minutes, and the import usually still completes.
A URL Google cannot fetch is left out of the response. It may still show up in the notebook with status: error, see GET /notebooks/notebook.
After a 504 or a timeout on your side, check the notebook with GET /notebooks/notebook before you retry. The import may still have completed, and a retry would add every source a second time.
https://api.useapi.net/v1/gemini-notebook/research/import
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
API tokenis required, see Setup useapi.net for details.
Request Body
{
"jobid": "job:526bc256-d897-493a-9ebc-7c9f35ca4428-user:[email protected]:gemini_notebook",
"urls": [
"https://www.nasa.gov/wp-content/uploads/static/history//alsj/a11/a11.1201-pa.html",
"https://www.ibiblio.org/apollo/Documents/CherryApollo11Exegesis.pdf"
]
}
jobidis required, the id of a completed research job from POST /research. The sources are added to that job’s notebook, on its account.urlsis optional, an array of up to500URLs taken from the job’sresult.sources.[]imports no sources.
Default: every source withcited: true.reportis optional,trueorfalse, whether to import the Deep Research report as a source.
Default:truewithouturls,falsewithurls.
Responses
-
The sources added, one entry each.
{ "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "sources": [ { "source": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:7eb13573-3089-45cd-a0c2-072e7550f58e", "title": "Apollo 11 Lunar Surface Journal: Program Alarms - NASA", "kind": "web", "status": "ready", "words": 1118, "url": "https://www.nasa.gov/wp-content/uploads/static/history//alsj/a11/a11.1201-pa.html", "created": "2026-09-29T04:20:12.000Z" }, { "source": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:45d05ce9-bb96-4195-87f4-dae61a37da23", "title": "Exegesis of the 1201 and 1202 Alarms Which Occurred During the Mission G Lunar Landing - Ibiblio", "kind": "pdf", "status": "ready", "words": 3739, "url": "https://www.ibiblio.org/apollo/Documents/CherryApollo11Exegesis.pdf", "created": "2026-09-29T04:20:12.000Z" } ] }A Deep Research report alone (
"urls": [], "report": true):{ "notebook": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55", "sources": [ { "source": "user:[email protected]:d02c903b-17f8-4241-a263-2be9e7359d55:3e0b77a3-88cb-43e2-8fd3-2cb956c6c6b3", "title": "Systemic Stress and Cascading Anomalies: An Engineering Analysis of the Apollo 11 Lunar Landing Near-Abort", "kind": "markdown", "status": "ready", "words": 2985, "created": "2026-09-29T04:15:32.000Z" } ] } -
A malformed parameter, a URL that is not in the result, nothing to import, a Drive file of an unknown type, or a job that is not a research job.
{ "error": "Not in this research result: https://example.com/not-there", "code": 400 }{ "error": "Nothing to import: pick urls and/or report", "code": 400 }The same
400answers a research job that found nothing (result.noResults: true).{ "error": "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 (job records are kept for 30 days), its account is no longer configured, or Google no longer has the notebook.
{ "error": "Job job:526bc256-…-bot:gemini_notebook not found", "code": 404 } -
The job is still running, or it failed or was cancelled. Only a completed research job can be imported.
{ "error": "Job job:0645b31d-ea2b-4c26-8754-a3b7876a21d0-user:[email protected]:gemini_notebook is failed; only a completed research job can be imported", "code": 409 } -
Google did not answer within about two minutes, or the connection dropped. The import usually still completes. Check the notebook before you retry, since a retry would add every source a second time.
{ "error": "Google did not answer the import (timeout or dropped connection). It may still have completed: check GET /notebooks/user%3A12345-user%40example.com-notebook%3Ad02c903b-17f8-4241-a263-2be9e7359d55 before retrying", "code": 504 } -
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 } -
Google is temporarily unavailable or is challenging our network. Retry in a few minutes. A
502means Google answered with an unexpected error.{ "error": "Google is temporarily unavailable (LBwxtb grpc 14), please retry", "code": 503 }
Model
The sources added, in the shape of POST /sources.
{ // TypeScript, all fields are optional
notebook: string // the research job's notebook
sources: {
source: string // user:<id>-<email>-source:<notebook uuid>:<source uuid>
title: string
kind: string // web, pdf, youtube, drive, google_docs, markdown (the report), see Source kinds
status: string // preparing | processing | ready | error
words?: number
url?: string // web page or YouTube URL
driveFileId?: string // Google Drive sources: the Drive file id
created?: string // ISO 8601
}[]
error: string // error responses only
code: number // error responses only, the HTTP status
}
Examples
-
curl -X POST "https://api.useapi.net/v1/gemini-notebook/research/import" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -d '{ "jobid": "job:139f798f-b450-45c3-9dfa-57cd9e8e8581-user:[email protected]:gemini_notebook" }' -
const token = "API token"; const apiUrl = "https://api.useapi.net/v1/gemini-notebook/research/import"; const response = await fetch(apiUrl, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}`, }, body: JSON.stringify({ jobid: "job:139f798f-b450-45c3-9dfa-57cd9e8e8581-user:[email protected]:gemini_notebook", urls: [], report: true }) }); const result = await response.json(); console.log("response", {response, result}); -
import requests token = "API token" apiUrl = "https://api.useapi.net/v1/gemini-notebook/research/import" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } data = { "jobid": "job:526bc256-d897-493a-9ebc-7c9f35ca4428-user:[email protected]:gemini_notebook", "urls": ["https://www.ibiblio.org/apollo/Documents/CherryApollo11Exegesis.pdf"] } response = requests.post(apiUrl, headers=headers, json=data) print(response, response.json())