# Image Search Download API (`truefetch/image-search-download-api`) Actor

An image download api that starts from a keyword instead of a URL list: search one or several of Google, Bing, Yahoo, Brave and Yandex and receive the image files themselves, 30 fields per row with byte-exact originals, JPEG/PNG/WebP copies, and SHA-256 hashes.

- **URL**: https://apify.com/truefetch/image-search-download-api.md
- **Developed by:** [TrueFetch](https://apify.com/truefetch) (community)
- **Categories:** Developer tools, AI, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.75 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Image Search Download API is an image download api that takes a keyword instead of a URL list, searches one or several of five engines in the same run, and hands back the image files themselves with 30 fields of provenance around each one.**

- **A keyword goes in, files come out.** Nothing upstream discovers URLs first: the run searches, downloads, decodes, and stores.
- **Both representations are kept.** The byte-exact original always, a JPEG, PNG, or WebP copy beside it when requested, a SHA-256 over each.
- **Thirty fields per row**, including the engine's own description, publisher, creator credits, and alternate variants, plus the decoded geometry and frame counts of both files.
- **Nothing is billed that was not delivered.** A row exists only once its original, output, JSON metadata record, and raw search response are all stored.

[**Run a one-result test**](https://apify.com/truefetch/image-search-download-api) · [**View API**](https://apify.com/truefetch/image-search-download-api/api)

One image on the FREE tier costs $0.04000 of Actor Start plus $0.00500, so the smallest useful test is $0.04500; the prefilled two-image test is $0.05000.

### What does Image Search Download API do?

It turns an image-search keyword into stored files and a record of where each came from. A run picks any combination of Google, Bing, Yahoo, Brave, and Yandex, reads each selected engine's result windows in turn, downloads and decodes each candidate, stores the original bytes untouched, optionally writes a JPEG, PNG, or WebP copy, and publishes one Dataset row per delivered file carrying the engine it came from.

What it is not: a URL-list downloader, a site crawler, or a reverse-image lookup. It takes no image as input, walks no website for image tags, decides nothing about reuse rights, and authenticates as nobody. The five engines are read as public search sources — no account, no key, no affiliation with Google, Microsoft, Yahoo, Brave, or Yandex.

### How do I run Image Search Download API?

1. Enter `keyword` — one phrase, up to 200 characters, sent to every selected engine exactly as typed.
2. Pick `platforms` — one or more of `google`, `bing`, `yahoo`, `brave`, `yandex`.
3. Pick `format` — `original` for the source bytes alone, or `jpeg`, `png`, `webp` to add a converted copy.
4. Set `max_results` — how many downloaded images to return from each selected engine. Minimum 1, no upper bound.
5. Start the run and read the default Dataset.

The smallest useful input, and the one the inputs arrive prefilled with:

```json
{
  "keyword": "vintage travel poster",
  "platforms": ["yandex"],
  "format": "png",
  "max_results": 2
}
```

`max_results` counts **delivered rows per selected engine**, not candidates examined — three engines at 10 return up to 30 rows. A candidate that 404s, refuses automated retrieval, or fails to decode is skipped and another is tried, so the number you set is the number of usable files you are asking to pay for from each engine. An image two selected engines both surface is downloaded, delivered, and billed once, against whichever engine reached it first.

### What data does Image Search Download API return?

One row per image downloaded, decoded, stored, and either preserved byte-exactly or converted. Every row carries the same 30 fields.

| Group | Fields |
| --- | --- |
| Search context | `platform`, `keyword`, `rank`, `title`, `description`, `publisher`, `creators`, `variants` |
| External links | `search_url`, `source_url`, `page_url`, `thumbnail_url` |
| Stored artifacts | `raw_url`, `original_url`, `image_url`, `metadata_url` |
| Decoded properties | `original_format`, `output_format`, `width`, `height`, `output_width`, `output_height`, `original_frames`, `output_frames`, `original_bytes`, `output_bytes`, `original_sha256`, `output_sha256` |
| Provenance | `processor`, `processed_at` |

`variants` lists alternate copies the engine reported, each with `url`, `width`, `height`, and `bytes` — that is how a job picks a resolution instead of taking whichever URL the result page exposed. `creators` holds credit strings the engine published: a lead for a licensing check, never a licence determination.

An illustrative row, abbreviated to 12 of the 30 fields:

```json
{
  "platform": "yandex",
  "keyword": "vintage travel poster",
  "rank": 1,
  "title": "Swiss Alps travel poster, 1935",
  "publisher": "example-archive.org",
  "source_url": "https://example-archive.org/posters/alps-1935.jpg",
  "original_url": "https://api.apify.com/v2/key-value-stores/example/records/original-image.jpg",
  "image_url": "https://api.apify.com/v2/key-value-stores/example/records/converted-image.png",
  "metadata_url": "https://api.apify.com/v2/key-value-stores/example/records/image-metadata.json",
  "original_format": "jpeg",
  "output_format": "png",
  "output_sha256": "39f78f2c453b0b86fe99a760678f0f4549f737c37e55638fca30bd13d27ee0f4"
}
```

Where the engine reports no value the field stays null rather than being filled in from elsewhere. Rows export as JSON, CSV, Excel, XML, RSS, or HTML; the binaries stay reachable through the URLs in the row.

### What inputs can I configure?

Four inputs, all required, in schema order.

| Input | Type | Required | Notes |
| --- | --- | --- | --- |
| `keyword` | string | Yes | One phrase, 200 characters or fewer, sent unmodified |
| `platforms` | array of enum | Yes | One or more of 5: `google`, `bing`, `yahoo`, `brave`, `yandex`, read in turn |
| `format` | enum | Yes | One of 4: `original`, `jpeg`, `png`, `webp` |
| `max_results` | integer | Yes | Per selected engine; minimum 1, no maximum |

No optional input, no per-engine configuration object, no filter beyond the four fields; the engine selection is the only thing that changes per run. Size, colour, licence, date, and safe-search facets are deliberately absent: the engines expose them inconsistently, and sending one an engine quietly ignores would make a filter look supported when it is not. `max_results` carries no ceiling on purpose — each engine's supply of usable candidates is the real limit, and the run reports what it delivered against what was asked for rather than refusing a large number up front.

### What platforms and markets does Image Search Download API cover?

Five engines, any combination of them per run, each read through its own public result pages:

| Engine | Candidates per window | Further windows | New images the next window added, over five keywords | Median request |
| --- | ---: | --- | ---: | ---: |
| `google` | 100 | yes | 77-94 | 64 s |
| `bing` | 35 | yes | 21-28 | 2.4 s |
| `yahoo` | 60 | yes | 39-60 | 2.6 s |
| `yandex` | 30 | yes | 18-30 | 3.0 s |
| `brave` | 200 | no | none | 2 s |

Those numbers come from 20 paged requests per engine across five keywords on 2026-09-02, counting only images not already seen in an earlier window. Brave has no second window, so a Brave run stops at 200 candidates however large `max_results` is; two full scans of it saved 198 and 199 files.

Market coverage is whatever the engine returns for the phrase, in whatever language; non-Latin keywords went through unchanged in that measurement. There is no country or locale input, because none of the five honours one consistently across the result shapes this reads — [Yandex's own documentation](https://yandex.com/support/images/search-results.html) describes the image results page and the metadata it exposes.

### Why use Image Search Download API?

Because the gap between "a search engine knows about this image" and "I have the file and can prove where it came from" is four separate jobs, and this closes all four in one call.

| Capability | What it saves you |
| --- | --- |
| Keyword to stored file in one request | No discovery step, no URL list, no separate downloader |
| Original bytes plus a converted copy | No encoder in your pipeline, no lost fidelity when you need the source later |
| SHA-256 over both files | Exact-duplicate detection without re-hashing downloads |
| One row shape across five engines | Switching or falling back between engines changes no downstream code |

The trade-off: this is search-driven, so it inherits the engine's opinion of the keyword, and no engine promises it indexes the largest version of a given image.

### Who is Image Search Download API for?

Developers and data teams building something that consumes image *files*, not image *links*.

- **Training and evaluation sets.** Collect a subject across engines, deduplicate on `original_sha256`, keep `source_url`, `publisher`, and `raw_url` as the provenance record a dataset review asks for.
- **Agent pipelines.** An agent asks for a keyword and gets stored assets with dimensions, formats, and hashes already measured, so nothing downstream opens a file to learn what it is.
- **Content tooling.** Pull references in one fixed output format and filter on `output_width` and `output_bytes` before a layout step sees them.
- **Monitoring.** Re-run the four fields on a schedule and diff `original_sha256` and `rank`.

Wrong tool for licence clearance, private or paywalled media, reverse-image matching, OCR, face detection, or any guarantee about a third-party host tomorrow.

### How can I use Image Search Download API through the API or MCP?

Use the name form `truefetch/image-search-download-api`; the immutable API ID is issued at first publication and the name form works everywhere the ID does. Start the run, poll it, then read its Dataset — never a synchronous shortcut, because the platform cuts a sync connection at 300 seconds without stopping the run, and a retry starts a second billed one.

```bash
RUN=$(curl -s -X POST "https://api.apify.com/v2/acts/truefetch~image-search-download-api/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keyword":"vintage travel poster","platforms":["yandex"],"format":"png","max_results":2}')
RUN_ID=$(echo "$RUN" | jq -r .data.id)

curl -s "https://api.apify.com/v2/actor-runs/$RUN_ID?token=$APIFY_TOKEN" | jq -r .data.status

curl -s "https://api.apify.com/v2/datasets/$(echo "$RUN" | jq -r .data.defaultDatasetId)/items?token=$APIFY_TOKEN"
```

Repeat the [run-status call](https://docs.apify.com/api/v2/actor-run-get) until `status` reads `SUCCEEDED`, or register an `ACTOR.RUN.SUCCEEDED` webhook and skip polling. Then fetch the [Dataset items](https://docs.apify.com/api/v2/dataset-items-get).

Through the Apify MCP server, call `truefetch/image-search-download-api` with `{"keyword":"vintage travel poster","platforms":["yandex"],"format":"png","max_results":2}`, then read the default Dataset and take `image_url` for the converted file or `original_url` for the source bytes. Generated SDK snippets and the OpenAPI definition are on the [API page](https://apify.com/truefetch/image-search-download-api/api).

### How much does Image Search Download API cost?

On the FREE tier each delivered image costs $0.00500, every run starts with $0.04000 of Actor Start, and the smallest useful one-image test totals $0.04500.

| Plan | Actor Start per run | Result: one delivered image |
| --- | ---: | ---: |
| FREE | $0.04000 | $0.00500 |
| BRONZE | $0.04000 | $0.00450 |
| SILVER | $0.04000 | $0.00400 |
| GOLD | $0.04000 | $0.00375 |
| PLATINUM | $0.04000 | $0.00375 |
| DIAMOND | $0.04000 | $0.00375 |

Actor Start bills one event per gigabyte of run memory with a one-event minimum, and this Actor's 4 GB makes that 4 × $0.01000 = $0.04000 on every run whatever it returns. Everything else bills per delivered row: a candidate that could not be downloaded, decoded, or stored produces no row and no charge. Because the start is fixed and the rows are not, a 100-image run at `$0.04000 + 100 × $0.00500 = $0.54000` costs $0.00540 per image against $0.04500 for a single-image run — batch the keyword rather than splitting it. Prices can change; current amounts are on the [pricing page](https://apify.com/truefetch/image-search-download-api/pricing).

### How does Image Search Download API compare with alternatives?

Doing it by hand is fine for a handful of files and better when a person judges each one before saving it. It stops scaling once the task also has to store originals, convert formats, hash files, and keep a provenance trail. Wiring it from separate pieces — search integration, downloader, encoder, hashing step — buys total control and four failure modes instead of one, which is right when the search side is already solved in your stack.

The engines' own interfaces win on exploration: facets this does not have, instant rendering, a human rejecting a bad candidate in a second. [Microsoft's licence-filter documentation](https://support.microsoft.com/en-us/bing/filter-images-by-license-type) states plainly that the originating site must still be checked, which is why nothing here claims a reuse right. An official search API fits better when its engine, quota, and metadata contract match and you never needed the bytes; a stock library fits better when cleared commercial licensing outranks open-web coverage. Do not choose this for a URL list, a known site, reverse-image search, or when one engine facet is the whole requirement.

### What are the limits and troubleshooting steps?

- **Fewer rows than `max_results`.** A candidate was removed at the source, refuses automated retrieval, exceeds the 40 MB source-file limit, decodes to more than 100 megapixels, or is not a decodable image. Retry later, or add another engine to `platforms`.
- **A Brave run stops at 200, or a run returns nothing.** Brave has one result window, so ask another engine for the remainder; an empty run means that phrase was temporarily unusable, so broaden it or switch engines.
- **`description`, `publisher`, `creators`, or `variants` is null.** The engine did not publish it. Alternate `variants` come from Yandex only; credits appear only where an engine exposes them.
- **A JPEG came back with a white background.** JPEG has no alpha channel, so transparency composites onto white. Ask for `png` or `webp` to keep it.
- **`output_frames` is 1 while `original_frames` is higher.** A conversion writes the first frame only; use `original` when the animation has to survive.
- **Near-identical files survive deduplication.** The hashes prove byte identity, not visual similarity. Add a perceptual hash downstream.

The smallest reproducible input is the prefilled `vintage travel poster` / `yandex` / `png` / `2`. For a defect report, open an [Issue](https://apify.com/truefetch/image-search-download-api/issues) with the run ID, the exact input, the affected `rank`, and which artifact URL failed. Never paste a token into an issue.

### Frequently asked questions

#### How do I download image search results as files?

Set `keyword`, pick one or more engines in `platforms`, pick a `format`, set `max_results`, and start the run. Each Dataset row links to the stored original and, when a conversion was requested, to the converted copy beside it.

#### Is there an image download api with sha-256 hashes?

Yes — every row carries `original_sha256` over the stored source bytes and `output_sha256` over the requested output, with `original_bytes` and `output_bytes` beside them, so both files verify independently after download.

#### Is there a free image search API?

Not an unlimited one. Runs can be tested with Apify credits, but FREE-tier billing is $0.04000 of Actor Start per run plus $0.00500 per delivered image.

#### Can I schedule runs to monitor image results over time?

Yes. Save the four fields as an Apify task, attach a schedule, and compare `rank`, `source_url`, and the two hashes between snapshots.

#### Does the row tell me who owns an image?

It tells you what the engine said: `publisher` and `creators` are reported values and `page_url` points at the context page when one was exposed. Treat all three as the start of a licensing check, never as permission.

#### Can it reach private, paid, or locked images?

No. Public search results and publicly retrievable image URLs only — no authentication, no guessed addresses, no working around access controls.

### Related TrueFetch Actors

- **[Multi Engine Search API](https://apify.com/truefetch/multi-engine-search-api)** — the same keyword-to-many-engines shape for web results instead of images, when you need the pages rather than the pictures.
- **[Best Video Downloader](https://apify.com/truefetch/best-video-downloader)** — the file-delivery counterpart for video, when a media pipeline needs moving assets stored the same way.
- **[Google Trends Explore](https://apify.com/truefetch/google-trends-explore)** — check whether a phrase is worth collecting for before spending a run on it.

### Support

The [API reference](https://apify.com/truefetch/image-search-download-api/api) and [pricing page](https://apify.com/truefetch/image-search-download-api/pricing) cover configuration and billing. Ask about keyword coverage, stored artifacts, formats, or hashing in the [TrueFetch community on Telegram](https://t.me/TrueFetch), and open an [Issue](https://apify.com/truefetch/image-search-download-api/issues) for anything reproducible.

[**Run a one-result test**](https://apify.com/truefetch/image-search-download-api) · [**View API**](https://apify.com/truefetch/image-search-download-api/api)

**Last Updated:** September 4, 2026

# Actor input Schema

## `keyword` (type: `string`):

The image-search phrase. Every engine you select is searched with it exactly as typed, and as many successfully downloaded images as 'max\_results' asks for are returned from each.

## `platforms` (type: `array`):

Which image engines answer this run: google, bing, yahoo, brave and yandex, one or more of them. Selected engines are read in turn and every row records the engine it came from. Google, Bing, Yahoo and Yandex read successive result windows to fill a large request; Brave answers from a single 200-result window. A Google window takes about a minute, the other four answer in seconds.

## `format` (type: `string`):

original returns the source bytes unchanged. jpeg, png and webp return a converted copy and keep the original beside it.

## `max_results` (type: `integer`):

How many successfully downloaded images to return from each engine you select — three engines at 10 return up to 30. The minimum is 1 and there is no upper bound; when an engine exposes fewer usable images the run reports how many it delivered against how many were asked for. An image two engines both surface is returned once, against whichever engine reached it first.

## Actor input object example

```json
{
  "keyword": "vintage travel poster",
  "platforms": [
    "yandex"
  ],
  "format": "png",
  "max_results": 2
}
```

# Actor output Schema

## `results` (type: `string`):

One row per saved image with original and output links, source description and variants, dimensions, animation frame counts, and metadata and raw search artifacts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keyword": "vintage travel poster",
    "platforms": [
        "yandex"
    ],
    "format": "png",
    "max_results": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("truefetch/image-search-download-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keyword": "vintage travel poster",
    "platforms": ["yandex"],
    "format": "png",
    "max_results": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("truefetch/image-search-download-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keyword": "vintage travel poster",
  "platforms": [
    "yandex"
  ],
  "format": "png",
  "max_results": 2
}' |
apify call truefetch/image-search-download-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,truefetch/image-search-download-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5PEUPkWGn13dGROHs/builds/oci8yFPPifUkr0N0v/openapi.json
