Skip to main content
Server SDKs

C# / .NET client reference

Constructor options, request types, responses, and errors.

Use public classes and records from the AffordableGeoApis namespace. Requires .NET 8 or later.

GeocodingClient​

new GeocodingClient(ClientOptions options, HttpMessageHandler? handler = null)
Task<GeocodingResponse> GeocodeAsync(AddressRequest request, CancellationToken cancellationToken = default)
Task<GeocodingResponse> SearchAsync(SearchRequest request, CancellationToken cancellationToken = default)
Task<GeocodingResponse> ReverseGeocodeAsync(ReverseRequest request, CancellationToken cancellationToken = default)
Task<AutocompleteResponse> AutocompleteAsync(AutocompleteRequest request, CancellationToken cancellationToken = default)
Task<GeocodingResult> ResolveAutocompleteAsync(AutocompleteSuggestion suggestion, CancellationToken cancellationToken = default)

Reuse one client to share fallback budgets and circuits. The client implements IDisposable; dispose it at application shutdown or use a using scope. All operations are asynchronous.

ClientOptions​

OptionTypeDefault / requirement
BaseUrlstringRequired origin/prefix; HTTPS except loopback HTTP
ApiKeystringRequired nonempty primary key
ConfidenceThresholddouble0.8; finite value in [0, 1]
FallbacksIReadOnlyList<FallbackOptions>Empty; used in configured order
FallbackOnIReadOnlyList<string>All five default triggers
MaxFallbackRequestslong?Unlimited if null; nonnegative integer at most 9007199254740991
FallbackCircuitBreakerCircuitBreakerOptions?Disabled if null
TimeoutMsint10000; positive integer at most 2147483647

FallbackOptions(string Provider, string ApiKey) accepts provider "google" or "here". CircuitBreakerOptions(int FailureThreshold, int CooldownMs) requires positive integers. FallbackOn accepts no_results, low_confidence, timeout, network, and server_error; an empty list disables triggered fallback. Country routing is independent of this list. Invalid options throw before making requests.

BaseUrl accepts HTTP only for localhost, localhost., 127.0.0.1, or [::1]. Embedded credentials, query strings, and fragments are rejected. It may include a deployment prefix but excludes the operation path.

The optional constructor handler accepts an HttpMessageHandler for a custom transport or mock. It must honor cancellation and disable redirects. The client owns and disposes it; the default transport disables redirects.

CancellationToken​

Each operation's optional CancellationToken controls caller cancellation and total deadlines. Omit it to apply only per-provider deadlines. Use CancellationTokenSource to set a total deadline across the chain. Caller cancellation throws OperationCanceledException, while per-provider timeouts use GeocodingError with code timeout.

Requests​

public sealed record AddressRequest(
string Street, // house number and street
string? City = null,
string? State = null,
string? Zip = null,
string? Country = null,
IReadOnlyList<string>? ExcludeSources = null
);

public sealed record ReverseRequest(
double Lat,
double Lon,
string? Country = null,
IReadOnlyList<string>? ExcludeSources = null
);

public sealed record Point(double Lat, double Lon);

public sealed record SearchRequest(
string Q, // 1–256 characters
string? Country = null,
Point? Near = null,
int? Limit = null, // 1–40, default 10
IReadOnlyList<string>? ExcludeSources = null
);

Primary geocode requests require at least one of city/state/ZIP. Country is an SDK routing hint for geocode and reverse and is not sent to primary; search also sends it as a filter. Invalid search values throw ArgumentException before networking. Nonempty hints outside CA/US/MX bypass primary. Country is never inferred from coordinates.

ExcludeSources serializes as exclude_sources and affects primary only. The API validates primary request fields; see geocode, search, reverse, and source exclusions.

Results and responses​

public sealed record GeocodingResult(
string Id, string Label, string Type, string HouseNumber, string Street,
string City, string State, string Zip, string Country,
double Lat, double Lon, double Confidence, string MatchType,
string Source, string Provider
);

public sealed record GeocodingResponse(
IReadOnlyList<GeocodingResult> Results,
string Provider,
string? FallbackReason,
IReadOnlyList<Attempt> Attempts,
JsonElement? ProviderResponse = null
);

public sealed record Attempt(
string Provider,
string Outcome,
string? SkipReason = null,
GeocodingError? Error = null
);

JsonElement is from System.Text.Json. Providers are primary, google, and here. FallbackReason is a default trigger or unsupported_country, or null when no fallback condition applies. Attempt outcomes are matched, no_results, low_confidence, error, and skipped. Skip reasons are budget_exhausted, circuit_open, and unsupported_country.

Missing text fields are empty strings. Street is the street name only. Type is address, venue, street, zip, neighborhood, borough, city, county, state, country, or empty; MatchType is primary-only (exact, interpolated, fallback). Result country is recognized ISO alpha-2 or an empty string. Confidence is numeric in [0, 1], with 0 for unavailable values; scores are not comparable across providers. Raw selected backup bodies are preserved; ProviderResponse is null for primary. See result semantics.

Serialize responses with JsonSerializer.Serialize(response, GeocodingClient.JsonOptions) for camelCase JSON and omitted optional null properties. FallbackReason remains an explicit JSON null when no fallback condition applies. The request property ExcludeSources maps to exclude_sources.

Autocomplete types​

public sealed record AutocompleteRequest(
string Q,
string Country,
Point? Near = null,
int? Limit = null,
IReadOnlyList<string>? ExcludeSources = null,
string? SessionToken = null
);

public sealed record AutocompleteSuggestion(
string Id, string Label, string Provider, string? SessionToken = null
);

public sealed record AutocompleteResponse(
IReadOnlyList<AutocompleteSuggestion> Suggestions,
string Provider,
string? FallbackReason,
IReadOnlyList<Attempt> Attempts,
JsonElement? ProviderResponse = null
);

AutocompleteRequest requires Q (1–256 nonblank characters) and a recognized Country. It accepts optional Near (a Point), Limit (1–10, default 5), ExcludeSources, and SessionToken. Near coordinates must be finite and within latitude ±90 and longitude ±180. An explicit session token must be nonblank and at most 256 characters. SessionToken groups Google Places requests across keystrokes; the client generates a UUID when omitted.

AutocompleteResponse contains suggestions and the same provider metadata as geocoding. Each suggestion includes its provider ID and label, with a session token for Google. Pass the suggestion unchanged to ResolveAutocompleteAsync; it returns a GeocodingResult with address fields and coordinates. Both methods accept a cancellation token. See address autocomplete.

Selection resolution​

Resolution returns the address directly, without an envelope, attempt history, or raw provider response. It calls only the suggestion's provider and bypasses fallback budgets/circuit breakers. Timeouts and caller cancellation still apply. An empty primary lookup throws GeocodingError with code provider_error. Google/HERE must be configured on the resolving client.

Resolution validates a known provider and a nonblank ID up to 256 characters. Primary resolution calls GET /v1/place?id=. SessionToken remains SDK-only.

GeocodingError​

Extends Exception, with Message, readonly Provider, readonly Code, nullable readonly Status, and readonly Attempts.

Code is http, network, timeout, invalid_response, provider_error, or unsupported_country. Terminal failures include the provider-chain history. Caller cancellation throws OperationCanceledException separately. Invalid local options or requests, including invalid Near coordinates, throw ArgumentException.

For structured logs, use JsonSerializer.Serialize(error, GeocodingClient.JsonOptions). Error JSON includes message, provider, code, optional status, and attempts without exception internals. Primary HTTP error messages include sanitized text from the error response body, limited to 512 characters; configured keys and HTTP URLs are redacted.