diff --git a/EXAMPLES.md b/EXAMPLES.md
index 9377b08bb..0d3ff62cc 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -7,9 +7,40 @@ Runnable examples live in [`examples/`](./examples).
## Table of Contents
+- [Blueprint with Build Context](#blueprint-with-build-context)
- [Devbox From Blueprint (Run Command, Shutdown)](#devbox-from-blueprint-lifecycle)
- [MCP Hub + Claude Code + GitHub](#mcp-github-tools)
+
+## Blueprint with Build Context
+
+**Use case:** Create a blueprint using the object store to provide docker build context files, then verify files are copied into the image. Uses the async SDK.
+
+**Tags:** `blueprint`, `object-store`, `build-context`, `devbox`, `cleanup`, `async`
+
+### Workflow
+- Create a temporary directory with sample application files
+- Upload the directory to object storage as build context
+- Create a blueprint with a Dockerfile that copies the context files
+- Create a devbox from the blueprint
+- Verify the files were copied into the image
+- Shutdown devbox and delete blueprint and storage object
+
+### Prerequisites
+- `RUNLOOP_API_KEY`
+
+### Run
+```sh
+uv run python -m examples.blueprint_with_build_context
+```
+
+### Test
+```sh
+uv run pytest -m smoketest tests/smoketests/examples/
+```
+
+**Source:** [`examples/blueprint_with_build_context.py`](./examples/blueprint_with_build_context.py)
+
## Devbox From Blueprint (Run Command, Shutdown)
diff --git a/examples/blueprint_with_build_context.py b/examples/blueprint_with_build_context.py
new file mode 100644
index 000000000..3bd9395d3
--- /dev/null
+++ b/examples/blueprint_with_build_context.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env -S uv run python
+"""
+---
+title: Blueprint with Build Context
+slug: blueprint-with-build-context
+use_case: Create a blueprint using the object store to provide docker build context files, then verify files are copied into the image. Uses the async SDK.
+workflow:
+ - Create a temporary directory with sample application files
+ - Upload the directory to object storage as build context
+ - Create a blueprint with a Dockerfile that copies the context files
+ - Create a devbox from the blueprint
+ - Verify the files were copied into the image
+ - Shutdown devbox and delete blueprint and storage object
+tags:
+ - blueprint
+ - object-store
+ - build-context
+ - devbox
+ - cleanup
+ - async
+prerequisites:
+ - RUNLOOP_API_KEY
+run: uv run python -m examples.blueprint_with_build_context
+test: uv run pytest -m smoketest tests/smoketests/examples/
+---
+"""
+
+from __future__ import annotations
+
+import tempfile
+from pathlib import Path
+from datetime import timedelta
+
+from runloop_api_client import AsyncRunloopSDK
+from runloop_api_client.lib.polling import PollingConfig
+
+from ._harness import run_as_cli, unique_name, wrap_recipe
+from .example_types import ExampleCheck, RecipeOutput, RecipeContext
+
+# building can take time: make sure to set a long blueprint build timeout
+BLUEPRINT_POLL_TIMEOUT_S = 10 * 60
+BLUEPRINT_POLL_MAX_ATTEMPTS = 600
+
+# configure object storage ttl for the build context
+BUILD_CONTEXT_TTL = timedelta(hours=1)
+
+
+async def recipe(ctx: RecipeContext) -> RecipeOutput:
+ """Create a blueprint with build context from object storage, then verify files in a devbox."""
+ cleanup = ctx.cleanup
+
+ sdk = AsyncRunloopSDK()
+
+ # setup: create a temporary directory with sample application files to use as build context
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ tmp_path = Path(tmp_dir)
+ (tmp_path / "app.py").write_text('print("Hello from app")')
+ (tmp_path / "config.txt").write_text("key=value")
+
+ # upload the build context to object storage
+ storage_obj = await sdk.storage_object.upload_from_dir(
+ tmp_path,
+ name=unique_name("example-build-context"),
+ ttl=BUILD_CONTEXT_TTL,
+ )
+ cleanup.add(f"storage_object:{storage_obj.id}", storage_obj.delete)
+
+ # create a blueprint with the build context
+ blueprint = await sdk.blueprint.create(
+ name=unique_name("example-blueprint-context"),
+ dockerfile="FROM ubuntu:22.04\nWORKDIR /app\nCOPY . .",
+ build_context=storage_obj.as_build_context(),
+ polling_config=PollingConfig(
+ timeout_seconds=BLUEPRINT_POLL_TIMEOUT_S,
+ max_attempts=BLUEPRINT_POLL_MAX_ATTEMPTS,
+ ),
+ )
+ cleanup.add(f"blueprint:{blueprint.id}", blueprint.delete)
+
+ devbox = await blueprint.create_devbox(
+ name=unique_name("example-devbox"),
+ launch_parameters={
+ "resource_size_request": "X_SMALL",
+ "keep_alive_time_seconds": 60 * 5,
+ },
+ )
+ cleanup.add(f"devbox:{devbox.id}", devbox.shutdown)
+
+ app_result = await devbox.cmd.exec("cat /app/app.py")
+ app_stdout = await app_result.stdout()
+
+ config_result = await devbox.cmd.exec("cat /app/config.txt")
+ config_stdout = await config_result.stdout()
+
+ return RecipeOutput(
+ resources_created=[
+ f"storage_object:{storage_obj.id}",
+ f"blueprint:{blueprint.id}",
+ f"devbox:{devbox.id}",
+ ],
+ checks=[
+ ExampleCheck(
+ name="app.py exists and readable",
+ passed=app_result.exit_code == 0,
+ details=f"exitCode={app_result.exit_code}",
+ ),
+ ExampleCheck(
+ name="app.py contains expected content",
+ passed='print("Hello from app")' in app_stdout,
+ details=app_stdout.strip(),
+ ),
+ ExampleCheck(
+ name="config.txt exists and readable",
+ passed=config_result.exit_code == 0,
+ details=f"exitCode={config_result.exit_code}",
+ ),
+ ExampleCheck(
+ name="config.txt contains expected content",
+ passed="key=value" in config_stdout,
+ details=config_stdout.strip(),
+ ),
+ ],
+ )
+
+
+run_blueprint_with_build_context_example = wrap_recipe(recipe)
+
+
+if __name__ == "__main__":
+ run_as_cli(run_blueprint_with_build_context_example)
diff --git a/examples/registry.py b/examples/registry.py
index 41a4b4b51..cb6b780a9 100644
--- a/examples/registry.py
+++ b/examples/registry.py
@@ -9,11 +9,19 @@
from .example_types import ExampleResult
from .mcp_github_tools import run_mcp_github_tools_example
+from .blueprint_with_build_context import run_blueprint_with_build_context_example
from .devbox_from_blueprint_lifecycle import run_devbox_from_blueprint_lifecycle_example
ExampleRegistryEntry = dict[str, Any]
example_registry: list[ExampleRegistryEntry] = [
+ {
+ "slug": "blueprint-with-build-context",
+ "title": "Blueprint with Build Context",
+ "file_name": "blueprint_with_build_context.py",
+ "required_env": ["RUNLOOP_API_KEY"],
+ "run": run_blueprint_with_build_context_example,
+ },
{
"slug": "devbox-from-blueprint-lifecycle",
"title": "Devbox From Blueprint (Run Command, Shutdown)",