Google SERP (Ace Data Cloud)
A Google search node for ComfyUI — and the JSON it actually hands you
- status
- task_id
- media_urls_json
- first_media_url
- result_json
- trace_id
AceGoogleSearchSerpGoogle is not a model. It's a search box bolted onto your graph: you give it a query, it calls Ace Data Cloud's hosted Google SERP API, and it hands you back structured results as a string. No weights, no VRAM, no GPU - it's an HTTP client wearing a ComfyUI hat, the pattern the KB calls an API-wrapper node.
Why reach for it? Plenty of workflows are starved for facts rather than pixels: pull current references before a prompt enhancer writes your prompt, grab a news summary for a script, or feed a downstream LLM node real search context instead of its own hallucinations. Search in, text out, into the text encoder - it writes no pixels, but it changes what your sampler is asked to draw.
How it works
One POST to https://api.acedata.cloud/serp/google with a bearer token from the environment. Before anything leaves your machine the payload is validated against the published JSON Schema, so a typo raises before authentication ever happens - nice, because a bad field can't cost you a credit.
The search is synchronous - no task to poll; you get results in the same run. One caveat from the KB's API-node chapter still applies: third-party pack, vendor org, credential held by design, repo three days old with zero stars. Read client.py (it's short) before you hand it a key. Credit where due, the key stays in the process environment rather than in your workflow JSON.
The inputs that matter
Of the nine widgets, only one is truly required by the API contract:
- query - the search string, up to 2048 characters. Blank it and the request is rejected as invalid, not sent.
- type - despite the name, this is the Google vertical:
search(default),images,news,maps,places,videos. - number - how many results, 1–100. The API's default is 3, stingier than you expect, and blank widgets just fall through to the contract defaults (
page: 1,type: search). - page - 1–100.
rangefilters by recency (h,d,w,m,y, or theqdr:spellings), andcountry/languagetake short region codes.image_sizeonly exists for theimagesvertical.
Everything else lives in parameters_json (default {}), which takes the same fields as an object - any non-empty widget overrides the matching JSON key, so use widgets for the obvious knobs and JSON for the rest:
{"query": "flux lora training dataset", "type": "news", "range": "w", "number": 10, "country": "us", "language": "en"}
What comes back
Six STRING outputs, and only one of them is the good one.
result_json holds the full normalized payload - status, success, task_id, trace_id, media_urls, and the actual results under data. Wire it into a PreviewAny or Show Text node (the pack ships that example), or convert a CLIP text-encode text widget to an input and inject it into a prompt. status is your quick check, and trace_id is what you quote at the vendor when something goes sideways. Sensitive keys are stripped on the way out, and error text is replaced with a pointer to that trace ID.
Two of the six will disappoint you. task_id comes back empty, because this endpoint answers synchronously - the README's "query the same task ID until it succeeds" line describes the rest of this vendor's node family, not this node, and no task-lookup node ships here anyway. And media_urls_json / first_media_url are usually empty for web results, since the client only harvests absolute URLs under keys like url or image_url. No media loader nodes ship in this version either, so don't plan on turning a result into an IMAGE.
Installing it
From ComfyUI Manager, search Google Search and confirm the publisher is acedatacloud - package Google Search by Ace Data Cloud, registry ID google-search. The listing is as new as the repo, so check you're not installing a lookalike.
Manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/AceDataCloud/GoogleSearchComfyUI
python -m pip install -r requirements.txt
# then restart ComfyUI
Dependencies are requests and jsonschema - probably already in your environment. No model downloads, no GPU, no version cliff (the README's ComfyUI 0.39.0 note is about media loaders this pack doesn't ship).
The key is the whole install. Create one in the Ace Data Cloud console, then put it in the environment of the process that launches ComfyUI - ACEDATACLOUD_API_KEY, or ACEDATACLOUD_API_TOKEN - and restart that process. Setting it in a different terminal, or after ComfyUI is already running under another shell, is the number one reason people see "Set ACEDATACLOUD_API_KEY in the ComfyUI process environment and restart." It's telling you the truth. The repo's only open issue is the author's own note that the docs never explain where the key comes from: console, Manage Keys, Create.
Things that will trip you up
Empty query. The most common error isn't a config problem, it's a blank field left in a loop. Blank it and you get Invalid query: does not meet the API's minLength constraint before any network call - no credit spent.
image_size without type: images. The schema has a oneOf that makes image size valid only for the images vertical; set it with the default type and you get a flat oneOf constraint complaint that explains nothing. Related: additionalProperties is false, so a stray key in parameters_json fails validation too, and page entered as letters is coerced to "page must be a number."
Money. These calls are metered. The client deliberately does not retry a paid submission after a connection failure - read-only lookups get three attempts, this one gets one - because a timeout doesn't prove the request wasn't accepted. If a run dies mid-flight, check your request history before hitting Queue Prompt again, or you'll pay twice for one search.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| parameters_json | STRING | {} | — |
| page | STRING | — | |
| type | STRING | — | |
| query | STRING | — | |
| range | STRING | — | |
| number | STRING | — | |
| country | STRING | — | |
| language | STRING | — | |
| image_size | STRING | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| status | STRING | — |
| task_id | STRING | — |
| media_urls_json | STRING | — |
| first_media_url | STRING | — |
| result_json | STRING | — |
| trace_id | STRING | — |