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

# Prefetching

> Start a company or styleguide lookup before your application needs the result.

Prefetch starts a company or styleguide lookup in the background. Use it when you learn a domain or work email before the next step needs that data. The later request may then reuse a cached result.

<Note>
  Prefetch costs 0 API credits and requires a paid subscription. It still uses the ordinary authenticated API rate limit.
</Note>

## Supported lookups

`POST /utility/prefetch` accepts one type and exactly one identifier:

| Data                  | Request body                                                   | Later operation        |
| --------------------- | -------------------------------------------------------------- | ---------------------- |
| Company by domain     | `{"type":"brand","identifier":{"domain":"stripe.com"}}`        | `POST /brand/retrieve` |
| Company by work email | `{"type":"brand","identifier":{"email":"founder@stripe.com"}}` | `POST /brand/retrieve` |
| Website styleguide    | `{"type":"styleguide","identifier":{"domain":"stripe.com"}}`   | `GET /web/styleguide`  |

Prefetch does not warm Markdown, HTML, screenshot, crawl, product, or structured-extraction operations.

## Queue a prefetch

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

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.context.dev/v1/utility/prefetch \
    --request POST \
    --header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "type": "brand",
    "identifier": {
      "email": "founder@acme.com"
    }
  }'
  ```

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

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

  const response = await client.utility.prefetch({
    type: "brand",
    identifier: {
      email: "founder@acme.com",
    },
  });

  console.log(response);
  ```

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

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

  response = client.utility.prefetch(
      type="brand",
      identifier={
        "email": "founder@acme.com",
      },
  )

  print(response)
  ```

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

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

  response = client.utility.prefetch(
    type: "brand",
    identifier: {
      "email" => "founder@acme.com",
    },
  )

  pp response
  ```

  ```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")))
      response, err := client.Utility.Prefetch(context.Background(), contextdev.UtilityPrefetchParams{
          Type: "brand",
          Identifier: contextdev.UtilityPrefetchParamsIdentifierUnion{
              OfByEmail: &contextdev.UtilityPrefetchParamsIdentifierByEmail{Email: "founder@acme.com"},
          },
      })
      if err != nil {
          panic(err)
      }
      fmt.Println(response)
  }
  ```

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

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

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

  $response = $client->utility->prefetch(
      type: "brand",
      identifier: [
        "email" => "founder@acme.com",
      ],
  );

  print_r($response);
  ```
</CodeGroup>

A successful response confirms that work was queued; it does not contain Brand or styleguide data. Treat the HTTP status and documented response fields as the contract rather than matching a human-readable message string.

## Retrieve the result later

Prefetch is asynchronous. Do not block the user while waiting for it or assume the work has completed after a fixed delay.

Retrieve the same company when the workflow needs it. The PHP example uses the SDK's low-level Brand request.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.context.dev/v1/brand/retrieve \
    --request POST \
    --header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "type": "by_domain",
    "domain": "acme.com",
    "timeoutMS": 60000
  }'
  ```

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

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

  const response = await client.brand.retrieve({
    type: "by_domain",
    domain: "acme.com",
    timeoutMS: 60000,
  });

  console.log(response.brand?.title);
  ```

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

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

  response = client.brand.retrieve(
      type="by_domain",
      domain="acme.com",
      timeout_ms=60000,
  )

  print(response.brand.title if response.brand else None)
  ```

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

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

  response = client.brand.retrieve(
    body: {
      "type" => "by_domain",
      "domain" => "acme.com",
      "timeout_ms" => 60000,
    }
  )

  puts response.brand&.title
  ```

  ```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")))
      response, err := client.Brand.Get(context.Background(), contextdev.BrandGetParams{
          OfByDomain: &contextdev.BrandGetParamsBodyByDomain{
              Domain:    "acme.com",
              TimeoutMs: param.NewOpt(int64(60000)),
          },
      })
      if err != nil {
          panic(err)
      }
      fmt.Println(response.Brand.Title)
  }
  ```

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

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

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

  // Use the SDK's low-level request: its generated Brand helper cannot express this lookup.
  $response = $client->request(
      method: 'post',
      path: 'brand/retrieve',
      body: [
        "type" => "by_domain",
        "domain" => "acme.com",
        "timeoutMS" => 60000,
      ],
  );
  $data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
  echo $data['brand']['title'] ?? 'No match', PHP_EOL;
  ```
</CodeGroup>

The later request can still be a cache miss if prefetch has not finished, failed, or targeted a different cache key. Keep the same timeout and fallback behavior you would use without prefetch.

## Good trigger points

* A work email becomes valid and remains unchanged after a debounce.
* A domain is saved on an earlier onboarding step.
* A background import discovers companies before enrichment begins.
* A user opens a workflow one step before Brand data is displayed.

Avoid starting prefetch on every keystroke or page render. Deduplicate work by normalized domain and do not prefetch consumer or disposable email providers.

## Handle expected errors

| Status and code                 | Meaning                                                        | Action                                                 |
| ------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------ |
| `400 INPUT_VALIDATION_ERROR`    | Both identifiers, neither identifier, or another invalid field | Fix the request.                                       |
| `403 FORBIDDEN`                 | Paid subscription required                                     | Skip prefetch; keep the later request path working.    |
| `422 FREE_EMAIL_DETECTED`       | Consumer email provider                                        | Ask for a work email or skip enrichment.               |
| `422 DISPOSABLE_EMAIL_DETECTED` | Disposable address                                             | Skip enrichment.                                       |
| `429 RATE_LIMITED`              | Current API window exhausted                                   | Honor `Retry-After`; do not create an unbounded queue. |

Do not catch every exception and silently discard it. Record the category so a broken credential or persistent service failure is distinguishable from an expected consumer-email rejection.

## Measure whether it helps

Track the later request's:

* `cache_metadata.status` and `age_ms`
* End-to-end latency
* Timeout rate
* Prefetch-to-retrieve interval
* Duplicate prefetch count per normalized domain

Prefetch is useful when it increases cache hits or reduces user-visible latency. It does not reduce the credit cost or rate-limit usage of the later retrieval.

## Next steps

<CardGroup cols={2}>
  <Card title="Prefetch API reference" icon="code" href="/api-reference/utility/prefetch">
    Review request fields and responses for domain and email prefetching.
  </Card>

  <Card title="Rate limits" icon="gauge-high" href="/optimization/rate-limits">
    Account for prefetch calls in your request budget.
  </Card>

  <Card title="Retrieve brand data" icon="building" href="/guides/get-brand-data">
    Retrieve the company profile after prefetching its domain.
  </Card>
</CardGroup>
