Skip to content

Add uploadImage for the Image API (F7) - #2

Open
jvmvik wants to merge 1 commit into
parity-fixesfrom
image-api
Open

jvmvik wants to merge 1 commit into
parity-fixesfrom
image-api

Conversation

@jvmvik

@jvmvik jvmvik commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Adds Image API support, so an uploaded image can be searched with Google Lens. Ported from serpapi-rust's image-api branch; serpapi-ruby's implement-image-api has the same shape.

Stacked on #1. The base is parity-fixes, so this diff shows only the upload. When #1 merges, GitHub retargets this PR to master.

var upload = try client.uploadImage("./image.jpg", .{});
defer upload.deinit();
const image_id = upload.value.object.get("image_id").?.string;
var results = try client.search(.{ .engine = "google_lens", .image_id = image_id });

Behavior

  • uploadImage(path, params) and uploadImageBytes(bytes, file_name, params), plus typed uploadImageAs / uploadImageBytesAs
  • POST https://serpapi.com/image, multipart/form-data:
    • The image goes in field image with its filename kept. Quotes and CR/LF in the name are escaped.
    • The content type is sniffed from the JPEG, PNG or WebP signature, then the extension.
  • api_key and source go in the body, never the URL. Constructor search defaults (engine, output, ...) are not sent. A call param named image is a compile error.
  • Images over 500 KiB (the server's limit, checked with curl) are rejected with error.ImageTooLarge before being read or sent.
  • The upload shares the request path with every GET: the timeout, the status check, the error payload rule, and lastError(). For a failed upload, lastError().url is https://serpapi.com/image.

Breaking change (shipping in 1.2.0 by decision)

serpapi.Error gains ImageTooLarge, so exhaustive switches over it need a prong.

Checks (merged with #1)

  • zig build lint: pass
  • zig build test: 41/41
  • zig build itest (live, SERPAPI_KEY set): 22/22, including upload from a file and from bytes, invalid image, invalid key, then a google_lens search on the uploaded image
  • zig build oobt: pass (search and upload)
  • Two review rounds (agent reviewer): approved with nits; all nits fixed.

Not included

There's no generated example yet: serpapi-library-tests-generator has no example.zig.erb template.

🤖 Generated with Claude Code

uploadImage(path, params) and uploadImageBytes(bytes, file_name, params),
plus the typed uploadImageAs / uploadImageBytesAs, POST the image to
https://serpapi.com/image as multipart/form-data and return its image_id
for engines such as Google Lens. Ported from serpapi-rust's image-api.

- the image goes in field `image`, filename kept (quotes and CR/LF
  escaped), content type sniffed from the JPEG/PNG/WebP signature, then
  the extension
- api_key and source travel in the body, never in the URL; constructor
  search defaults (engine, output, ...) are not sent; a call param named
  `image` is a compile error
- images over 500 KiB are rejected with error.ImageTooLarge before being
  read or sent
- the upload shares fetch with every GET: the timeout race, the status
  check, the error payload rule, and lastError(), whose url is
  https://serpapi.com/image for a failed upload
- live tests: upload from a file and from bytes, invalid image, invalid
  key, then a google_lens search on the uploaded image; oobt also uploads

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant