Use HttpClient with the experimental Cloud API; no VisionScan NuGet scanning package is published.
Status
Experimental
Integration
Cloud REST client
Distribution
HTTP API
Version
0.1.0-RC4
Prerequisites
.NET 8 or newer
VISIONSCAN_CLOUD_URL
VISIONSCAN_ACCESS_TOKEN
A supported image file
1. Use the framework HTTP client
Use the framework HTTP client
dotnet new console --framework net8.0
No VisionScan NuGet dependency is required for the REST contract.
2. Configure HttpClient
Configure HttpClient
using var client = new HttpClient { BaseAddress = new Uri(cloudUrl), Timeout = TimeSpan.FromSeconds(30) };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
Use IHttpClientFactory in long-lived ASP.NET applications.
3. Upload and submit
Upload and submit
var upload = await PostAsync<UploadResponse>(client, "/v1/uploads", new { idempotencyKey = Guid.NewGuid(), contentBase64 = Convert.ToBase64String(image), contentType = "image/png" });
var job = await PostAsync<JobResponse>(client, "/v1/jobs", new { idempotencyKey = Guid.NewGuid(), uploadIds = new[] { upload.uploadId }, profile = "still-image-dense" });
var status = await client.GetFromJsonAsync<JobStatus>($"/v1/jobs/{job.jobId}");
EnsureSuccessStatusCode before deserializing each response.
Errors and recovery
Condition
Resolution
Deserialization returns null
Preserve the HTTP status and structured error body; do not turn a malformed response into an empty result.
409 idempotency conflict
Use the original payload or issue a new key for changed content.
Production checklist
Use IHttpClientFactory
Set bounded timeouts and cancellation
Redact authorization headers
Do not claim a native .NET SDK
Public contract reference
These are the callable methods and HTTP operations used by this guide. Inputs, results, lifecycle rules, and denial behavior are part of the versioned customer contract.
Cloud upload contract
Upload bytes are authenticated, bounded, MIME-checked, idempotent, and tenant-scoped.
POST /v1/uploads
http
Persist one validated image and return a tenant-scoped upload identifier.
Inputs for POST /v1/uploads
Input
Type
Required
Meaning
Authorization
Bearer token
Yes
Production RS256 token with bounded time claims and cloud-scan entitlement.
idempotencyKey
UUID/string
Yes
Tenant-scoped key reused only for an identical retry.
contentBase64
base64 string
Yes
Locally bounded PNG, JPEG, or WebP bytes.
contentType
string
Yes
image/png, image/jpeg, or image/webp matching the file magic bytes.
Result
2xx JSON containing uploadId and non-sensitive upload metadata.
Lifecycle
Upload before creating a job; retain the idempotency key for retries of the same bytes.
Trust boundary
Tenant and site come only from the verified token; request bodies cannot override tenant scope.
Failure behavior
401/403 for invalid or unentitled identity.
409 for a reused key with different content.
4xx for invalid MIME, magic bytes, base64, or size; 429 for quota limits.
Cloud job creation contract
A job references same-tenant uploads and selects a bounded scan profile.
POST /v1/jobs
http
Create an asynchronous scan job from one or more previously accepted uploads.
Inputs for POST /v1/jobs
Input
Type
Required
Meaning
idempotencyKey
UUID/string
Yes
Tenant-scoped key for identical job retries.
uploadIds
string[]
Yes
Existing upload IDs owned by the authenticated tenant and site.
profile
string
Yes
An allowlisted profile such as still-image-dense.
callback
HTTPS URL
No
Optional policy-validated callback; production delivery requires the documented callback controls.
Result
2xx JSON containing jobId, queued status, and correlation metadata.
Lifecycle
Create after uploads succeed, then poll status until completed or failed.
Trust boundary
Callbacks reject non-HTTPS and non-global destinations, pin validated addresses, follow no redirects, and HMAC-sign payloads.