C# REST INTEGRATION

Integrate screenshots with C# and a reusable HttpClient

Snapshot Site does not currently ship an official .NET SDK. Use HttpClient and System.Net.Http.Json for typed REST requests, keep the API key in server configuration, validate the JSON result, and stream generated images or PDFs into storage owned by your application.

Direct REST
No official .NET package claimed
HttpClient
Reusable managed transport
Typed JSON
System.Net.Http.Json
Install:Use System.Net.Http.Json from modern .NET
Auth:SNAPSHOT_SITE_API_KEY
Get started for free
C# HTTP workflow
C# backend using a reusable HTTP client and secure JSON request to download a website screenshot
Good fits
ASP.NET Core services and background workers
Scheduled report and document generation
Visual QA and monitoring pipelines
Teams using IHttpClientFactory and typed options

Use established .NET HTTP patterns

The API is JSON over HTTPS with header authentication. A small typed client can fit existing dependency injection, configuration, resilience, logging, and cancellation conventions without inventing a package surface.

1

Create a typed client

Register a named or typed HttpClient and keep endpoint details inside one adapter rather than scattering raw requests through controllers.

2

Serialize request records

Use operation-specific records with the exact JSON property names documented by the screenshot, analyze, and compare endpoints.

3

Pass CancellationToken

Propagate cancellation through the API request and asset download so background jobs stop cleanly.

4

Validate before download

Check the API error indicator and required fields before following a returned link or publishing an output.

Quick start

Capture a page from C#

1

Read SNAPSHOT_SITE_API_KEY from secure application configuration

2

Register one reusable HttpClient with an appropriate timeout

3

Post a typed request with the API key header

4

Deserialize and validate the result before downloading the asset

C# screenshot API example

.NET

Typed screenshot request with cancellation

This example uses framework HTTP and JSON APIs. It is a direct REST client, not an official Snapshot Site NuGet package.

using System.Net.Http.Json;
using System.Text.Json.Serialization;

var apiKey = Environment.GetEnvironmentVariable("SNAPSHOT_SITE_API_KEY")
  ?? throw new InvalidOperationException("SNAPSHOT_SITE_API_KEY is required");

using var client = new HttpClient
{
  BaseAddress = new Uri("https://api.prod.ss.snapshot-site.com"),
  Timeout = TimeSpan.FromSeconds(50),
};
client.DefaultRequestHeaders.Add("x-snapshotsiteapi-key", apiKey);

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(45));
var request = new CaptureRequest(
  "https://example.com",
  "webp",
  1440,
  true,
  true
);

using var response = await client.PostAsJsonAsync(
  "/api/v1/screenshot",
  request,
  cts.Token
);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync<CaptureResponse>(
  cancellationToken: cts.Token
) ?? throw new InvalidOperationException("Empty response");

if (result.Error || string.IsNullOrWhiteSpace(result.Link))
  throw new InvalidOperationException(result.Message ?? "Capture failed");

Console.WriteLine(result.Link);

record CaptureRequest(
  [property: JsonPropertyName("url")] string Url,
  [property: JsonPropertyName("format")] string Format,
  [property: JsonPropertyName("width")] int Width,
  [property: JsonPropertyName("fullSize")] bool FullSize,
  [property: JsonPropertyName("hideCookie")] bool HideCookie
);

record CaptureResponse(
  [property: JsonPropertyName("error")] bool Error,
  [property: JsonPropertyName("message")] string? Message,
  [property: JsonPropertyName("link")] string? Link
);

Why this is a REST guide rather than a NuGet SDK page

Snapshot Site has no official .NET package today. A page that invented a package name, methods, or support policy would create false expectations. The stable integration surface is the REST API, which modern .NET applications can call with built-in HTTP and JSON support.

A focused typed client is typically a small amount of code. It should reflect application conventions for dependency injection, options, logging, cancellation, resilience, and storage instead of creating a second infrastructure stack just for screenshots.

Register the client correctly

Prefer IHttpClientFactory in ASP.NET Core

Register a typed or named HttpClient with the base address and a timeout appropriate to rendering work. Inject the API key through options backed by a secret provider. Keep endpoint paths and headers inside the adapter.

Do not instantiate and dispose a new client for every controller call in a long-running service. Managed connection reuse is one of the reasons to follow the framework pattern.

For a command-line job, a single reused client for the process is sufficient. The important rule is to avoid recreating the transport for every item in a batch.

Use operation-specific records

Create separate request and response records for screenshot, analyze, and compare. Their payloads differ and benefit from different validation. Explicit JsonPropertyName attributes remove ambiguity around names such as fullSize and hideCookie when the project has a different global naming policy.

Model only fields the application uses, but include the documented error and message information necessary for operations. Treat a missing required output link as a failure even when deserialization succeeds.

Validate target configuration

Keep target URLs and capture options in a domain-level job configuration. Validate format, viewport, and business permissions before making the request. If users can submit arbitrary URLs, apply the product's destination policy and authorization boundary before they reach the adapter.

Cancellation, timeouts, and background work

Pass a CancellationToken through PostAsJsonAsync, response parsing, and asset download. In ASP.NET Core this may begin with the request token; in a BackgroundService it should come from the worker lifecycle and job deadline.

Browser rendering can take longer than a database lookup or internal JSON endpoint. Choose a bounded request timeout based on observed pages and required delay. Do not set an infinite timeout, and do not copy a two-second internal-service policy that makes legitimate renders fail.

For interactive workflows, decide whether a user should wait or receive a job identifier. Batch, schedule, PDF, and full-page work often belong in a queue or background worker where progress and retries are explicit.

Parse API outcomes carefully

First check the transport response. Then deserialize the JSON and inspect API-level error fields. Some validation or rendering outcomes may arrive as a JSON error payload, so EnsureSuccessStatusCode alone is not a complete success condition.

Convert failures into a small application error model with operation, sanitized target identifier, retryability where available, and message. Avoid logging the API key, authorization headers, or complete URLs that contain private query parameters.

Retry only failures classified as transient. Use bounded exponential backoff with jitter and observe cancellation. Invalid options and authentication failures should fail the job immediately and produce a configuration issue.

Stream generated outputs

The capture response returns a link. When the asset needs durable ownership, download it into application storage. Use HttpCompletionOption.ResponseHeadersRead or an equivalent streaming pattern for large files, validate content type and size, and copy into a file or object-storage stream.

Store the source identifier, request configuration, capture time, and resulting storage key in the same record. A screenshot without its configuration is difficult to reproduce and risky to use as an audit artifact.

Apply an idempotent output key for scheduled or batch work. A retry should resolve to the same intended report or capture slot instead of creating an unrelated duplicate.

C# integration patterns

Background monitoring service

A hosted worker can read approved targets, limit parallel calls with SemaphoreSlim or a bounded channel, compare results with stored baselines, and write review items. The Website Monitoring API explains baseline ownership and alert context.

Report and PDF generation

Build a stable report URL, request format: pdf, validate the result, and stream the document into approved storage. Protect preview routes containing business or customer data and avoid permanent public tokens.

Release evidence

Run a small capture matrix after deployment and attach images or diffs to the release record. Keep viewport and timing fixed so comparisons measure the application rather than configuration drift.

Security and capacity

Use an approved secret provider and restrict access to the typed client. Do not forward arbitrary injected page code from an unauthenticated web request. Sanitize logging and apply retention rules to captures that may contain business-sensitive information.

Bound parallelism according to the plan and workload. A Task.WhenAll over thousands of targets creates a burst; a bounded channel or worker pool provides controlled throughput and easier cancellation.

C# integration checklist

  1. Register a reusable named or typed HttpClient.
  2. Inject the API key from secure server-side configuration.
  3. Define separate typed models for each operation.
  4. Propagate cancellation and set realistic bounded timeouts.
  5. Check transport and JSON application outcomes.
  6. Stream durable assets into controlled storage.
  7. Bound parallelism and retry only transient failures.
  8. Test invalid input, cancellation, partial batches, and download errors.

C# screenshot API FAQ

Is there an official Snapshot Site .NET or C# SDK?

No. Snapshot Site currently publishes official TypeScript, Python, and PHP SDKs. This page documents direct REST calls using .NET framework APIs.

Should ASP.NET Core use IHttpClientFactory?

Usually yes. Register a named or typed client so connection management, configuration, logging, and resilience policy follow the application's existing conventions.

Can I use PostAsJsonAsync for screenshot requests?

Yes. System.Net.Http.Json can serialize a typed request into the JSON body. Make sure property names match the documented API fields.

How should I handle timeouts?

Set a bounded HttpClient timeout and pass a CancellationToken from the request or background job. Browser rendering can need more time than a normal internal API call.

Can C# call analyze and compare?

Yes. Define separate records for those documented REST payloads and responses rather than overloading the screenshot types.

How should I download the returned asset?

Use a separate HTTP GET, validate the status and content type, and stream the response into a file or object store. Avoid buffering large full-page assets unnecessarily.

Where should the API key be stored?

Use environment-backed configuration, a secret manager, or another approved server-side provider. Never put the key in browser code, source control, or a target URL.

How should retries be configured?

Apply bounded retries only to transient outcomes, with backoff and jitter. Do not retry invalid payloads, missing credentials, or other permanent failures.

Add one typed Snapshot Site client to your .NET service

Start with the screenshot operation, follow existing HttpClient and configuration conventions, then add analyze or compare only when the product uses them.