Skip to main content
Server

C# / .NET SDK

Geocoding from C#. Install, authenticate, and make your first call.

The .NET SDK includes typed requests, normalized results, and optional Google/HERE fallbacks. It uses HttpClient and System.Text.Json and has no third-party runtime dependencies.

Installation​

Requires .NET 8 or later. The package is not yet published to NuGet. Add a local project reference from your application directory. Replace the path with your checkout:

Add the SDK to your application
dotnet add reference /path/to/pelias/sdk/dotnet/src/AffordableGeoApis/AffordableGeoApis.csproj

Quick start​

Create a client with your deployment URL and API key, then submit an address:

C#
using AffordableGeoApis;

using var client = new GeocodingClient(new ClientOptions
{
BaseUrl = Environment.GetEnvironmentVariable("GEOCODING_BASE_URL")!,
ApiKey = Environment.GetEnvironmentVariable("GEOCODING_API_KEY")!,
});

var response = await client.GeocodeAsync(new AddressRequest(
Street: "11 Wall Street",
City: "New York",
State: "NY",
Zip: "10005"
));

foreach (var result in response.Results)
{
Console.WriteLine($"{result.Label}: {result.Lat}, {result.Lon}");
}

Results is a list of address candidates. Check that it is nonempty before selecting a candidate. A no-match request succeeds with an empty list.

Examples use top-level statements and the implicit System imports enabled by current .NET console templates. In a class-based application, await SDK calls inside an async method.

Authentication​

Set the primary URL and key in your backend environment:

Environment
export GEOCODING_BASE_URL='http://localhost:8000'
export GEOCODING_API_KEY='YOUR_API_KEY'

Pass both values to the constructor as shown above. The SDK sends the key in the apikey header. Use your assigned HTTPS URL in production; the base URL excludes /v1/geocode. Keep all provider keys on your backend.

Available methods​

MethodUse
client.GeocodeAsync(request, cancellationToken)Find coordinates for a street address
client.SearchAsync(request, cancellationToken)Find addresses and places from one line of free text
client.ReverseGeocodeAsync(request, cancellationToken)Find address candidates for coordinates
client.AutocompleteAsync(request, cancellationToken)Suggest addresses for partial text and a required country
client.ResolveAutocompleteAsync(suggestion, cancellationToken)Resolve the selected suggestion into one address

The cancellation token is optional. Geocode, search, and reverse geocode return Task<GeocodingResponse>. Autocomplete returns Task<AutocompleteResponse>; resolution returns Task<GeocodingResult>. See the client reference for request and result types.

Common operations​

var response = await client.SearchAsync(new SearchRequest(
Q: "11 Wall Street, New York, NY",
Country: "US",
Limit: 5
));

foreach (var result in response.Results)
{
Console.WriteLine($"{result.Label}: {result.Lat}, {result.Lon}");
}

Search accepts one line of text, such as an address, place name, city, or ZIP code, and returns matches of any type. Q is required (1 to 256 characters). Country restricts results, Near: new Point(lat, lon) prefers nearby results, and Limit is 1 to 40 (default 10). Use geocode when the address is already split into fields. See search.

Address autocomplete​

var response = await client.AutocompleteAsync(new AutocompleteRequest(
Q: "11 Wall",
Country: "US",
Limit: 5
));
if (response.Suggestions.Count > 0)
{
var address = await client.ResolveAutocompleteAsync(response.Suggestions[0]);
Console.WriteLine($"{address.Label}: {address.Lat}, {address.Lon}");
}

Keep the suggestion object unchanged until selection. Resolution calls only its provider and does not run fallback selection or use fallback budgets/circuits. See autocomplete.

Reverse geocoding​

var response = await client.ReverseGeocodeAsync(new ReverseRequest(
Lat: 40.7074,
Lon: -74.0113
));

foreach (var result in response.Results)
{
Console.WriteLine(result.Label);
}

Excluding a data source​

var response = await client.GeocodeAsync(new AddressRequest(
Street: "11 Wall Street",
City: "New York",
ExcludeSources: ["osm"]
));

Exclusions affect primary candidates only. ExcludeSources maps to the HTTP field exclude_sources. See data sources.

C# types​

AddressRequest request = new(Street: "11 Wall Street", City: "New York");
GeocodingResponse response = await client.GeocodeAsync(request);

Request and response properties use PascalCase. All SDK types are in the AffordableGeoApis namespace.

Configuration​

Provider fallbacks​

Add the providers you want to call, in order:

using var client = new GeocodingClient(new ClientOptions
{
BaseUrl = Environment.GetEnvironmentVariable("GEOCODING_BASE_URL")!,
ApiKey = Environment.GetEnvironmentVariable("GEOCODING_API_KEY")!,
ConfidenceThreshold = 0.8,
MaxFallbackRequests = 1000,
Fallbacks = [
new("google", Environment.GetEnvironmentVariable("GOOGLE_MAPS_API_KEY")!),
new("here", Environment.GetEnvironmentVariable("HERE_API_KEY")!),
],
});

The first nonempty backup wins when primary has no results, low confidence, or an eligible outage. Backups are off by default. A request with Country: "GB" skips primary and uses configured backups. See fallback policy for triggers, budgets, and circuit breakers.

Error handling​

try
{
await client.GeocodeAsync(new AddressRequest("11 Wall Street", City: "New York"));
}
catch (GeocodingError error)
{
Console.Error.WriteLine($"{error.Code} {error.Status}: {error.Message}");
foreach (var attempt in error.Attempts)
{
Console.Error.WriteLine($"{attempt.Provider}: {attempt.Outcome}");
}
}

Primary HTTP 4xx and malformed responses do not trigger fallback. Terminal provider errors include the complete attempt history. Caller cancellation throws OperationCanceledException separately.

Timeouts and cancellation​

Each provider request times out after ten seconds by default. Set constructor TimeoutMs to change it. To bound the whole provider chain:

using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(15));
var response = await client.GeocodeAsync(
new AddressRequest("11 Wall Street", City: "New York"),
deadline.Token
);

Pass a CancellationToken for caller-controlled cancellation. Cancellation throws OperationCanceledException and stops the chain.

Retries​

The SDK does not retry automatically. If your application retries, bound the attempts and use backoff. Each call can consume primary and backup usage.

Raw provider response​

if (response.ProviderResponse is { } body)
{
Console.WriteLine(body.GetRawText());
}

ProviderResponse contains the full parsed body of the selected Google/HERE response as a nullable JsonElement. It is null for primary results. To serialize the normalized response with camelCase fields, use JsonSerializer.Serialize(response, GeocodingClient.JsonOptions) from System.Text.Json.

Reuse a client to share fallback budgets and circuits. Dispose it when your application shuts down; using var disposes it at the end of its scope.

For partial address entry, see address autocomplete.