# Adobe Stock Scraper: Assets, Keywords & Portfolio Changes (`vant47/adobe-stock-scraper`) Actor

Monitor Adobe Stock search results and contributor portfolios: titles, asset keywords, dimensions, AI flags, previews and repeat observations. Missing dates and download/view counts stay null. $0.0005 per asset: 1,000 cost $0.50, plus a $0.0023 start/GB (minimum one unit). No login.

- **URL**: https://apify.com/vant47/adobe-stock-scraper.md
- **Developed by:** [fortbrand](https://apify.com/vant47) (community)
- **Categories:** E-commerce, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 assets

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Adobe Stock Scraper: Assets, Keywords & Portfolio Changes

For contributors, creative research teams and catalog analysts who want an exportable record of Adobe Stock search results and contributor portfolios. Collect asset-specific keywords, titles, public creator attribution, dimensions, AI flags, preview links and the license information Adobe supplies. About **$0.0005 per delivered asset**, plus **$0.0023 per allocated GB to start (minimum one unit)**. At the default 1 GB, **20 assets cost $0.0123** and **1,000 assets cost $0.5023** at the base rate. No Adobe login or Adobe API key is required.

Use the same input repeatedly to observe which asset IDs appear in your selected search or portfolio. Turn on `compareWithPreviousRun` to add a previous observation timestamp to assets already seen in a completed run. Export the unique-asset table as JSON, CSV or Excel.

### What you get

Each row identifies a public Adobe Stock asset. Search suggestions are never presented as an asset's keywords. The keyword list comes from the individual asset's public metadata. Connection sessions can be reused anonymously; asset metadata is fetched again on each run. Repeated appearances across your selected searches or portfolios produce one delivered asset and one asset charge in that run.

| Field | Meaning |
| --- | --- |
| `verdict` | A readable media label and asset title. |
| `recordType` | `ASSET` for useful data; `NOTE` for a free explanation. |
| `assetId` | Adobe Stock asset identifier, stored as a string. |
| `title` | Title supplied by Adobe Stock. |
| `mediaType` | Media category from Adobe type IDs and format flags; `mediaTypeId` retains the source ID. |
| `creatorId` | Public contributor identifier when supplied. |
| `creatorDisplayName` | Public creator attribution shown with the asset. |
| `contributorUrl` | Link to the public contributor portfolio. |
| `keywords` | Asset-specific keyword strings from the public metadata. |
| `category` | Adobe Stock category name when available. |
| `width`, `height` | Original asset dimensions, not thumbnail dimensions. |
| `uploadedAt` | Upload timestamp if exposed; otherwise null. |
| `isGenerativeAI` | Supplied generative-AI flag; absent flags remain null. |
| `downloadCount`, `viewCount` | Numeric public counters if supplied; otherwise null. |
| `licensePrice`, `currency` | Numeric price for the default license when explicitly supplied. |
| `previewUrl` | Public preview or thumbnail link, not a licensed original. |
| `url` | The public Adobe Stock asset page. |
| `scrapedAt` | Time this metadata was observed, in UTC. |
| `previousSeenAt` | Earlier observation timestamp, added only when one exists. |
| `downloadDelta`, `viewDelta` | Added only when both observations contain the corresponding numeric counter. |

Additional fields keep the source's pricing distinctions: `licensePriceText`, `licenseOptions` and `extendedLicensePrice`. A blank standard-license amount stays null even when the extended license has a visible price. An extended-license price must not be mistaken for the standard-license price. `isFireflyGenerated` preserves the separate source flag when present. `source` and `sourceType` identify the input that first delivered an asset.

The **ASSETS** and **NOTES** views focus on their respective columns. Their linked clean exports omit rows without those fields. Each run also saves a **SUMMARY** key-value record containing the delivered count, contributor count, source outcomes, duplicate exclusions, free failures and spending-limit status. Inspect SUMMARY before treating an empty dataset as evidence that a portfolio or search is empty.

### Start in three steps

1. Enter topics in `searchTerms`, contributor portfolio links in `contributorUrls`, or Adobe Stock links in `startUrls`.
2. Choose your media filters, public sort order and global asset limit.
3. Run the Actor, inspect SUMMARY and export the ASSETS view.

The prefill searches coffee with a 20-asset limit. A cloud verification on 5 November 2026 delivered 20 distinct assets with 20 asset charges in 52 seconds. Asset-specific keywords were present, and duplicate IDs were absent. Network conditions and source responses vary. Cloud checks also completed two runs of 1,100 unique assets each, with one asset charge per row and zero source failures.

### Inputs

| Input | Behavior and example |
| --- | --- |
| `searchTerms` | An array such as `["coffee", "renewable energy"]`. |
| `contributorUrls` | Public URLs such as `https://stock.adobe.com/contributor/203434592/chayathon2000`. |
| `startUrls` | Public asset, keyword-search or contributor URLs on stock.adobe.com. |
| `sortBy` | `relevance`, `newest` or `downloads`; default relevance. |
| `mediaTypes` | Optional array: photo, illustration, vector, video, template, 3d or audio. Empty uses Adobe's combined search; select audio explicitly for music. |
| `includeGenerativeAI` | True by default. False requests Adobe's exclusion filter and excludes assets explicitly flagged as AI-generated. |
| `compareWithPreviousRun` | False by default. True remembers a completed observation for matching source/filter settings. |
| `maxItems` | Global unique-asset limit from 1 to 10,000; default 20. |
| `proxyConfiguration` | Optional proxy settings. The automatic route starts with the default datacenter pool and uses US residential only after fresh-session retries. |

At least one source selector is required. Invalid values produce a free note and an invalid-input summary. They do not produce asset charges. Enter complete HTTPS links. Links to unrelated domains, account pages, download endpoints and private dashboards are not accepted as source selectors.

Sources share one global cap and are visited one page at a time in input order. A page can contribute up to 100 assets, so a smaller cap may be filled by the first source. For fixed per-query allowances, use separate runs. Repeated IDs are free.

A multi-topic scan:

```json
{
  "searchTerms": ["coffee", "renewable energy", "healthy food"],
  "sortBy": "relevance",
  "mediaTypes": ["photo"],
  "includeGenerativeAI": false,
  "maxItems": 300
}
```

A repeatable contributor observation:

```json
{
  "contributorUrls": [
    "https://stock.adobe.com/contributor/203434592/chayathon2000"
  ],
  "sortBy": "newest",
  "compareWithPreviousRun": true,
  "maxItems": 100
}
```

For known assets, supply their public pages in `startUrls`. Search sorting does not change the identity of a requested exact asset. An unavailable asset is explained without an asset charge. Keyword-search links can retain their public URL filters; the explicit sort and media settings on the Actor form take precedence where they address the same filter.

### Example asset

The following values were checked against the public asset data on 5 November 2026. This example is shortened to keep the fields readable:

```json
{
  "assetId": "94143804",
  "title": "cup of coffee latte in coffee shop",
  "mediaType": "photo",
  "creatorId": "203434592",
  "creatorDisplayName": "chayathon2000",
  "contributorUrl": "https://stock.adobe.com/contributor/203434592/chayathon2000",
  "keywords": ["hot drink", "latte", "art", "cafes", "drink", "hot", "cup", "espresso", "shop"],
  "category": "Coffee",
  "width": 4928,
  "height": 3280,
  "uploadedAt": null,
  "isGenerativeAI": false,
  "downloadCount": null,
  "viewCount": null,
  "licensePrice": null,
  "extendedLicensePrice": 79.99,
  "currency": "USD",
  "url": "https://stock.adobe.com/images/cup-of-coffee-latte-in-coffee-shop/94143804"
}
```

### Monitor a portfolio or search again

Save your preferred input as an Apify task and attach an Apify schedule. A schedule runs the same source selectors and filters again and stores a separate dataset for each run. Webhooks can pass the successful run's dataset ID to your database, spreadsheet or automation platform. Keep the task input stable when comparing observations.

With `compareWithPreviousRun: true`, the first completed run establishes a baseline. Later matching runs add `previousSeenAt` for assets in that baseline. `observationStatus` distinguishes the baseline, previously observed assets and newly observed assets. `changedFields` lists observed changes in titles, keywords, dimensions, category, creator attribution, AI flags and license amounts. SUMMARY identifies the baseline run and counts newly observed and changed assets. The comparison is scoped to the calling Apify user, this Actor and the selected sources and filters. Completed observations replace the baseline; partial or invalid runs retain it.

An asset without `previousSeenAt` has no matching earlier observation in that baseline. This does not establish when it was uploaded to Adobe Stock. An asset absent from a capped or reordered result set has not necessarily been deleted. For stronger longitudinal comparisons, monitor exact asset links, retain your own historical datasets and record the cap and filters alongside them.

Counters are never reconstructed from search position or download sorting. A view or download delta is emitted only when Adobe supplies numeric values in both observations. Null is a missing value, not zero. Keep those distinctions when building charts, aggregations or alerts.

### Pricing

One delivered unique asset is one **Asset** charge. Asset retries, duplicates, free notes and SUMMARY are not asset charges. The minimum start charge is disclosed separately. Your Apify subscription tier determines the asset rate:

| Plan | Per asset | 100 assets | 1,000 assets |
| --- | ---: | ---: | ---: |
| Free | $0.0005 | $0.05 | $0.50 |
| Bronze | $0.000475 | $0.0475 | $0.475 |
| Silver | $0.00045 | $0.045 | $0.45 |
| Gold and higher | $0.0004 | $0.04 | $0.40 |

The table shows asset charges only. Add **$0.0023 per GB of allocated memory, minimum one unit**, on every plan. At the default 1 GB this adds $0.0023; selecting 2 GB adds $0.0046. Apify charges this start fee automatically, including runs that return only notes, empty results or failures. Those results have no asset charge. The minimum permitted run budget is $0.0028, covering the default start plus one base-rate asset; allocate a higher budget when selecting 2 GB. This start fee is higher than the earlier private-test fee of $0.00005. Asset prices and tier discounts are unchanged, and small-job totals are higher than in those earlier tests.

At the default 1 GB, total examples including the start fee are:

| Plan | 1 asset | 2 assets | Default 20 assets | 1,000 assets |
| --- | ---: | ---: | ---: | ---: |
| Free | $0.0028 | $0.0033 | $0.0123 | $0.5023 |
| Bronze | $0.002775 | $0.00325 | $0.0118 | $0.4773 |
| Silver | $0.00275 | $0.0032 | $0.0113 | $0.4523 |
| Gold and higher | $0.0027 | $0.0031 | $0.0103 | $0.4023 | Set the run's maximum charge to control the total. The Actor checks the remaining allowance before preparing a delivery batch and stops cleanly when it cannot deliver another paid asset. There is no separate keyword-enrichment charge or default dataset-item charge.

### API and integrations

Use your Apify token in a secret environment variable; no Adobe credentials are needed.

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_APIFY_TOKEN")
run = client.actor("vant47/adobe-stock-scraper").call(
    run_input={
        "searchTerms": ["renewable energy"],
        "maxItems": 100,
        "compareWithPreviousRun": True,
    }
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("recordType") == "ASSET":
        print(row["assetId"], row["title"], row["keywords"])
```

Use each run's returned dataset ID. Export JSON or CSV, connect Make, n8n, Zapier or Sheets, and retain SUMMARY with the export for coverage context.

### Use with AI agents (MCP)

An AI agent connected to `https://mcp.apify.com` can read the Actor's schema, choose a global cap and start a run. Name the source and wanted fields: “Collect 100 Adobe Stock coffee photos with asset-specific keywords, creator attribution and dimensions, excluding generative AI.” For portfolio work, give the public contributor link and ask the agent to inspect SUMMARY after the run.

Ask the agent to preserve nulls in any resulting table. It should not describe missing counters as zero downloads, turn newest ordering into an upload timestamp, or label a returned preview as a licensed image. The Actor's structured fields and source URLs let your agent make those distinctions explicitly.

### Limits

Only public signed-out metadata is collected. The tested website routes do not expose numeric download/view counts or upload dates consistently; these fields remain null when absent. Most standard-image license prices are blank, while an extended-license amount may be visible. A listed amount is not a personalized checkout quote. Search ordering is supplied by Adobe and can change between runs. A capped portfolio observation does not prove additions or removals across the whole portfolio. Adobe can challenge or refuse anonymous traffic; exhausted retries produce free notes and partial coverage in SUMMARY. No login, account cookies, CAPTCHA solving, paid unblocking, licensed originals, contact details or private contributor dashboards are used. Public preview links remain subject to Adobe's rights and availability. Metadata is requested in English; a regional URL prefix does not select a locale. Public prices depend on the visitor context. The Actor is independently maintained and is not affiliated with Adobe.

### FAQ

**Are the keywords really specific to each asset?** Yes. The Actor requests the asset's own public keyword list. It does not substitute suggested searches or words inferred from the title.

**Can I monitor a contributor without searching a topic?** Yes. Supply the public portfolio link in `contributorUrls`. The resulting rows retain their public creator IDs and attribution.

**What does downloads ordering mean if downloadCount is null?** Adobe can provide an ordering without publishing a numeric count in the same response. The Actor preserves that distinction and does not estimate a number.

**Does one asset in two searches cost twice?** No. Within a run, the asset ID is the deduplication key. The same asset observed in a later run is a new observation and is charged when delivered again.

**Will I receive a licensed original?** No. You receive metadata and public preview links. Licensing an asset remains a separate action with Adobe Stock.

**Why was my result empty?** Inspect SUMMARY and the NOTES view. They distinguish invalid input, empty public results, refused requests, unavailable assets and the spending limit.

# Actor input Schema

## `searchTerms` (type: `array`):

Topics such as coffee or renewable energy. Results rotate across the selected sources until maxItems is reached.

## `contributorUrls` (type: `array`):

Public Adobe Stock contributor URLs.

## `startUrls` (type: `array`):

Public stock.adobe.com asset, keyword-search or contributor URLs.

## `sortBy` (type: `string`):

Adobe Stock public ordering. Downloads ordering is not a numeric download count.

## `mediaTypes` (type: `array`):

Optional media filter: photo, illustration, vector, video, template, 3d or audio. Empty uses Adobe Stock combined search; select audio explicitly for music.

## `includeGenerativeAI` (type: `boolean`):

Include AI-generated assets when true. False applies Adobe Stock exclusion and checks supplied flags.

## `compareWithPreviousRun` (type: `boolean`):

Remember completed runs for this same source/filter selection. Adds previousSeenAt for assets seen before; numeric deltas only if both observations supply a numeric counter.

## `maxItems` (type: `integer`):

Global unique-asset limit across all selected sources. Each delivered asset costs $0.0005 at base pricing, plus $0.0023 per allocated GB to start (minimum one unit). At the default 1 GB, 20 assets total $0.0123. The start fee also applies to empty or invalid runs.

## `proxyConfiguration` (type: `object`):

Default datacenter pool first, US residential only after fresh-session retries. Anonymous sessions only.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee"
  ],
  "sortBy": "relevance",
  "includeGenerativeAI": true,
  "compareWithPreviousRun": false,
  "maxItems": 20
}
```

# Actor output Schema

## `assets` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `notes` (type: `string`):

No description

# 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 = {
    "searchTerms": [
        "coffee"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("vant47/adobe-stock-scraper").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 = {
    "searchTerms": ["coffee"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("vant47/adobe-stock-scraper").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 '{
  "searchTerms": [
    "coffee"
  ],
  "maxItems": 20
}' |
apify call vant47/adobe-stock-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vant47/adobe-stock-scraper"
        }
    }
}
```

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/hvt5h0VNEiPU6smNt/builds/qIvlrOD64nqO995fS/openapi.json
