> ## Documentation Index
> Fetch the complete documentation index at: https://docs.context.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Extract page images

> Return an image manifest from a webpage, with optional dimensions, hosted copies, visual classification, and deduplication.

Use `GET /web/scrape/images` to find images referenced by a webpage. Results can include `<img>` sources, inline SVG, responsive sources, metadata images, favicons, CSS backgrounds, and video posters.

## Prerequisites

Export an API key from the [dashboard](https://context.dev/dashboard):

```bash theme={null}
export CONTEXT_DEV_API_KEY="ctxt_secret_..."
```

## Find images

The base request returns where each image was found, its source value, source type, and alt text when available.

<CodeGroup>
  ```bash cURL theme={null}
  curl --get https://api.context.dev/v1/web/scrape/images \
    --header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --data-urlencode "url=https://example.com"
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({
    apiKey: process.env.CONTEXT_DEV_API_KEY,
  });

  const page = await client.web.webScrapeImages({
    url: "https://example.com",
  });

  console.log(page.images);
  ```

  ```python Python theme={null}
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  page = client.web.web_scrape_images(url="https://example.com")
  print(page.images)
  ```

  ```ruby Ruby theme={null}
  require "cgi/core"
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  page = client.web.web_scrape_images(url: "https://example.com")
  puts page.images
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk/v2"
      "github.com/context-dot-dev/context-go-sdk/v2/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      page, err := client.Web.WebScrapeImages(context.Background(), contextdev.WebWebScrapeImagesParams{
          URL: "https://example.com",
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(page.Images)
  }
  ```

  ```php PHP theme={null}
  <?php

  require __DIR__.'/vendor/autoload.php';

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $page = $client->web->webScrapeImages(url: 'https://example.com');
  print_r($page->images);
  ```
</CodeGroup>

The base request costs 1 credit, or 2 credits when it includes browser actions.

## Enrich the images

Request enrichment only when you need to select, store, or categorize assets:

<CodeGroup>
  ```bash cURL theme={null}
  curl --get https://api.context.dev/v1/web/scrape/images \
    --header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --data-urlencode "url=https://example.com" \
    --data-urlencode "dedupe=true" \
    --data-urlencode "enrichment[resolution]=true" \
    --data-urlencode "enrichment[hostedUrl]=true" \
    --data-urlencode "enrichment[classification]=true"
  ```

  ```typescript TypeScript theme={null}
  const page = await client.web.webScrapeImages({
    url: "https://example.com",
    dedupe: true,
    enrichment: {
      resolution: true,
      hostedUrl: true,
      classification: true,
    },
  });
  ```

  ```python Python theme={null}
  page = client.web.web_scrape_images(
      url="https://example.com",
      dedupe=True,
      enrichment={
          "resolution": True,
          "hosted_url": True,
          "classification": True,
      },
  )
  ```

  ```ruby Ruby theme={null}
  require "cgi/core"
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))

  page = client.web.web_scrape_images(
    url: "https://example.com",
    dedupe: true,
    enrichment: {
      resolution: true,
      hosted_url: true,
      classification: true,
    },
  )

  puts page.images
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk/v2"
      "github.com/context-dot-dev/context-go-sdk/v2/option"
      "github.com/context-dot-dev/context-go-sdk/v2/packages/param"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      page, err := client.Web.WebScrapeImages(context.Background(), contextdev.WebWebScrapeImagesParams{
          URL: "https://example.com",
          Dedupe: param.NewOpt(true),
          Enrichment: contextdev.WebWebScrapeImagesParamsEnrichment{
              Resolution: param.NewOpt(true),
              HostedURL: param.NewOpt(true),
              Classification: param.NewOpt(true),
          },
      })
      if err != nil {
          panic(err)
      }

      fmt.Println(page.Images)
  }
  ```

  ```php PHP theme={null}
  <?php

  require __DIR__.'/vendor/autoload.php';

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $page = $client->web->webScrapeImages(
      url: 'https://example.com',
      dedupe: true,
      enrichment: [
          'resolution' => true,
          'hostedURL' => true,
          'classification' => true,
      ],
  );

  print_r($page->images);
  ```
</CodeGroup>

Setting any enrichment flag makes the entire request cost 5 credits, including a request that also uses browser actions.

## Read the result

```json theme={null}
{
  "success": true,
  "url": "https://example.com",
  "images": [
    {
      "src": "https://example.com/hero.png",
      "element": "img",
      "type": "url",
      "alt": "Example product dashboard",
      "enrichment": {
        "width": 1600,
        "height": 900,
        "mimetype": "image/png",
        "url": "https://media.brand.dev/example.png",
        "type": "photography"
      }
    }
  ],
  "cache_metadata": {
    "status": "miss",
    "age_ms": 0
  }
}
```

The `src` field can be an absolute URL, inline HTML such as SVG markup, or a base64 data URI. Branch on each item's `type` before downloading or rendering it.

## Choose enrichment

| Requirement                       | Option                           | Returned fields                                   |
| --------------------------------- | -------------------------------- | ------------------------------------------------- |
| Compare image size                | `enrichment.resolution=true`     | `width`, `height`                                 |
| Store a materialized copy         | `enrichment.hostedUrl=true`      | `url`, `mimetype`                                 |
| Separate photos, logos, and icons | `enrichment.classification=true` | visual `type`                                     |
| Collapse perceptual duplicates    | `dedupe=true`                    | highest-resolution member of each duplicate group |

Classification values are `photography`, `illustration`, `logo`, `wordmark`, `icon`, `pattern`, `graphic`, or `other`. Treat the value as a useful label, not proof that an asset is approved for a specific use.

## Load more images

Use `waitForMs` for short delayed loads. Use [browser actions](/guides/browser-actions) when the page needs a click or scroll before images appear.

<CodeGroup>
  ```bash cURL theme={null}
  curl --get https://api.context.dev/v1/web/scrape/images \
    --header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --data-urlencode "url=https://example.com/gallery" \
    --data-urlencode 'actions=[{"do":"scroll","amount":"viewport","maxScrolls":5}]'
  ```

  ```typescript TypeScript theme={null}
  import ContextDev from "context.dev";

  const client = new ContextDev({apiKey: process.env.CONTEXT_DEV_API_KEY});
  const url = "https://example.com/gallery";

  const page = await client.web.webScrapeImages({url}, {
    query: {
      url,
      actions: JSON.stringify([
        {
          "do": "scroll",
          "amount": "viewport",
          "maxScrolls": 5
        }
      ]),
    },
  });

  console.log(page.images);
  ```

  ```python Python theme={null}
  import json
  import os
  from context.dev import ContextDev

  client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])

  page = client.web.web_scrape_images(
      url="https://example.com/gallery",
      extra_query={
          "actions": json.dumps([
            {
              "do": "scroll",
              "amount": "viewport",
              "maxScrolls": 5
            }
          ]),
      },
  )

  print(page.images)
  ```

  ```ruby Ruby theme={null}
  require "cgi/core"
  require "json"
  require "context_dev"

  client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
  actions = [{do: "scroll", amount: "viewport", maxScrolls: 5}]

  page = client.web.web_scrape_images(
    url: "https://example.com/gallery",
    request_options: {extra_query: {"actions" => [JSON.generate(actions)]}},
  )

  puts page.images
  ```

  ```go Go theme={null}
  package main

  import (
      "context"
      "fmt"
      "os"

      contextdev "github.com/context-dot-dev/context-go-sdk/v2"
      "github.com/context-dot-dev/context-go-sdk/v2/option"
  )

  func main() {
      client := contextdev.NewClient(
          option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
      )

      page, err := client.Web.WebScrapeImages(
          context.Background(),
          contextdev.WebWebScrapeImagesParams{URL: "https://example.com/gallery"},
          option.WithQuery("actions", `[{"do":"scroll","amount":"viewport","maxScrolls":5}]`),
      )
      if err != nil {
          panic(err)
      }

      fmt.Println(page.Images)
  }
  ```

  ```php PHP theme={null}
  <?php

  require __DIR__.'/vendor/autoload.php';

  use ContextDev\Client;

  $client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));

  $page = $client->web->webScrapeImages(
      url: 'https://example.com/gallery',
      actions: [
          ['do' => 'scroll', 'amount' => 'viewport', 'maxScrolls' => 5],
      ],
  );

  print_r($page->images);
  ```
</CodeGroup>

The TypeScript, Python, Ruby, and Go examples send actions as a JSON query value to preserve the array in SDK 2.14.0.

## Production behavior

* Results describe assets referenced by the rendered page. They do not guarantee that every URL remains downloadable later.
* `alt` can be `null`; do not use it as the only source of an accessible label in your product.
* `maxAgeMs` defaults to one day, accepts up to 30 days, and can be set to `0` for a fresh scrape.
* Forwarding custom `headers` bypasses cache reads and writes.
* Use the returned `cache_metadata` to distinguish a hit, miss, or honored ZDR request.

## Next steps

<CardGroup cols={1}>
  <Card title="Images API reference" icon="code" href="/api-reference/web-scraping/images">
    Review the complete image schema and error responses.
  </Card>
</CardGroup>
