AWS Bedrock with .NET: Getting Started
The Problem: Too Many APIs, Too Much Friction
Imagine this: your team decides to add AI to your .NET application. You pick a model, wire up the HTTP client, handle the auth, parse the response schema—and it works. Then the product team asks to try a different model. Suddenly you have two HTTP clients, two authentication flows, two response formats, and twice the maintenance burden. Add a third model and things start to spiral.
This is the reality that many .NET teams hit when integrating generative AI directly through vendor APIs. Each provider has its own conventions, and none of them speak fluent C#.
What is AWS Bedrock and Why Use It from .NET?
AWS Bedrock is Amazon's answer to the multi-model problem. It gives you a single, consistent interface to access foundation models from providers like Anthropic Claude and Amazon Titan—without juggling separate APIs, auth tokens, or request formats for each one.
Think of Bedrock as a universal adapter—like those laptop power converters that work worldwide. You plug in once, and voltage, plug shape, and frequency differences disappear. Similarly, your .NET code plugs into Bedrock once, and differences between Claude, Titan, and other models are handled at the API layer.
What makes it especially compelling for .NET developers is the official AWS SDK for .NET. You can invoke powerful AI models using idiomatic C# code, plugging straight into your existing projects—no context switching, no foreign tooling. Text generation, summarization, intelligent chat—all accessible through the same familiar patterns you already use for other AWS services.
At a high level, every Bedrock request follows this flow:
Why: The Need for Simplicity, Security, and Scale
- Simplicity: One unified API for all models instead of managing multiple SDKs and auth flows.
- Security: Enterprise-grade access control via AWS IAM—no custom auth layers.
- Scale: Built-in monitoring and throttling for production use.
How: Step-by-Step Guide to Using AWS Bedrock from .NET
Let's get hands-on with setup, authentication, and your first invocation.
1. Prerequisites
- AWS account with Bedrock access
- AWS credentials configured via
aws configure - .NET 9 SDK or later
- NuGet packages:
AWSSDK.Bedrock,AWSSDK.BedrockRuntime
2. Setting Up Your Project
dotnet add package AWSSDK.Bedrock
dotnet add package AWSSDK.BedrockRuntime
3. Authenticating with AWS
Run aws configure and enter your credentials. The SDK automatically reads from ~/.aws/credentials:
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
4. Quick Checks Before Invoking
- Credentials missing? Check
~/.aws/credentials(or%USERPROFILE%\.aws\credentialson Windows). - Model not found? Request access in AWS Console → Bedrock → Model access (5–15 min wait).
- Wrong region? Claude 3 Haiku is in
us-east-1andus-west-2only. Check model availability. - Package version? Use AWSSDK.BedrockRuntime 3.7.0 or later.
5. Quick Start: Your First Model Invocation
Now that everything is configured and common pitfalls are clear, let's get hands-on and invoke Claude. Here's a real, working example from the ai-playground repository that demonstrates how to build a practical Bedrock application:
public async Task<string> GetMovieDetails(string movieQuery)
{
// Build the prompt for Claude models: must start with "\n\nHuman: " and end with "\n\nAssistant:"
var prompt =
$"\n\nHuman: You are a movie information expert. Provide detailed information about the movie '{movieQuery}'. " +
"Return the results as a JSON array of objects with the following fields: title (string), year (integer), " +
"category (string, Movie/TV), directors (array of strings), actors (array of strings), plot (string), genre (string), rating (string). " +
"If no movie is found, return an empty JSON array.\n\nAssistant:";
var request = new InvokeModelRequest
{
ModelId = "anthropic.claude-3-haiku-20240307-v1:0",
ContentType = "application/json",
Accept = "application/json",
Body = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(
JsonSerializer.Serialize(new
{
anthropic_version = "bedrock-2023-05-31",
max_tokens = 1024,
messages = new[]
{
new { role = "user", content = prompt }
}
})
))
};
var response = await _client.InvokeModelAsync(request);
var responseBody = System.Text.Encoding.UTF8.GetString(response.Body.ToArray());
return FormatJsonString(responseBody);
}
What's happening:
- You craft a structured prompt that tells Claude exactly what format to return (JSON with specific fields).
- You create an
InvokeModelRequestwith your model ID and serialized prompt. - The SDK sends the request to Bedrock. Claude processes it and returns structured movie data as JSON.
- You parse the response and return it to the caller.
This example shows why Bedrock is powerful: one unified C# API to get smart, JSON-formatted responses from Claude. Users can add similar methods for classification, summarization, extraction, or chat—all using the same pattern.
6. Building Production Systems: Efficient Batching
For scale, batch requests using Task.WhenAll. With 10,000 items at 1-2 seconds each, sequential processing takes 3–6 hours; batching (size 10–20) reduces this to ~15 minutes.
- Batch size: Start with 10–20, tune based on throttling. Us-east-1 allows higher throughput.
- Error handling: Implement exponential backoff for throttling. Queue failed items for async retry.
- Idempotency keys: Include item IDs or timestamps to prevent re-processing on retries.
⚠️ Pitfalls to Avoid & Limitations to Know
Before shipping Bedrock to production, understand these real-world constraints. They won't stop you, but they will catch you off guard if you're unprepared.
Regional Availability
Claude 3 Haiku/Sonnet are in us-east-1 and us-west-2. Titan Text is more widely available. ModelNotFound errors are usually region mismatches—always check region first.
Rate Limits & Quotas
Bedrock enforces account-specific quotas to protect infrastructure. The default is commonly around 100 requests per minute per model, though this varies by region, account age, and model.
Exceed your quota and you'll get a ThrottlingException. In production, implement exponential backoff and request a higher quota from AWS Support if needed.
Pricing impact: Bedrock charges per input + output token. A 1000-ticket batch can run approximately $5–20 depending on model and verbosity (check current pricing for exact rates). Always estimate costs before scaling.
Model Differences Matter
Claude 3 models have different characteristics. Note: Pricing and latency figures change frequently. Check the AWS Bedrock pricing page for current rates:
- Haiku (fastest, cheapest): Best for simple tasks like classification and extraction. Lowest latency.
- Sonnet (balanced): Better reasoning than Haiku. Mid-range cost and latency. Suitable for most applications.
- Opus (most capable, if available): Check AWS docs—may not be available in all regions or via Bedrock.
- Token limits vary: Check the model documentation for current context window sizes.
7. Summary
- What: AWS Bedrock is a managed service that abstracts vendor-specific AI APIs into a unified interface (with C# SDK support).
- Why: It reduces friction: unified auth (IAM), consistent error handling, and easy model switching.
- How: Use
InvokeModelfor single requests and batch operations. In production, batch efficiently, handle throttling gracefully, and forecast costs.
This approach lets you build intelligent, generative features into your .NET apps with clarity and control. Whether you're prototyping or going to production, AWS Bedrock and .NET make GenAI accessible and robust.
8. References & Further Reading
For reference, the code repository being discussed is available at github: https://github.com/ajaysskumar/ai-playground
Thanks for reading through. Please share feedback, if any, in comments or on my email ajay.a338@gmail.com
