---
title: "C# API client | Customer&#x27;s Canvas Hub"
canonical: "https://customerscanvas.com/docs/hub/dev-center/api/clients/cs-api-client/"
---

# C# API client

> Customer's Canvas provides a powerful REST API for managing designs, assets, and backend services. Each service has its own package in Nuget. This tutorial demonstrates how to use the official C# API Client to interact with the API. We'll create a simple controller to fetch a list of designs.

We will assume that you already have an instance of Customer's Canvas set up and running on our infrastructure or your servers.

## 1. Create a project

1. In Visual Studio, create a new project, either **ASP.NET Web Application (.NET Framework)** or **ASP.NET Core Web Application**.
2. When creating the project, use the **Web API** project template.
3. Ensure **64-bit IIS Express** is enabled:
    - In the menu, click **Tools** > **Options** > **Projects and Solutions** > **Web Projects**.
    - Select **Use the 64 bit version of IIS Express for web sites and projects**.

## 2. Install NuGet packages
 
For the purposes of this tutorial, let's install the `Aurigma.AssetStorage.ApiClient` by typing the following command in the Visual Studio Package Manager Console:

```bash
Install-Package Aurigma.AssetStorage.ApiClient
```

Refer to the [full list](https://customerscanvas.com/docs/hub/dev-center/api/clients.md#net-client) of available packages.

## 3. Set Up API Clients

The C# API Client uses **dependency injection (DI)** for configuration. We support both **.NET Core** and **.NET Framework** (with Autofac). You may use another IoC container if you prefer.

**.NET Core**

Find the `ConfigureServices` method in **Startup.cs**. Here, we will put the API client configuration code: 

```csharp title="ConfigureServices example"
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    ConfigureSwagger(services);

    services.AddAuthentication("Bearer")
        .AddJwtBearer("Bearer", options =>
        {
            options.Authority = "http://localhost:21021";

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateAudience = false
            };

            options.RequireHttpsMetadata = false;
        });

    services.AddSingleton<IAuthorizationHandler, IdentityAuthenticatedUserAuthorizationHandler>();
    services.AddSingleton<IAuthorizationHandler, ApiKeyAuthenticatedUserAuthorizationHandler>();
    services.AddAuthorization(options =>
    {
        options.AddPolicy("Custom",
            policy => policy.Requirements.Add(new AuthenticatedUserAuthorizationRequirement()));
    });

    ConfigureDesignAtomsApiClients(services);
    ConfigureAssetProcessorApiClients(services);
    ConfigureAssetStorageApiClients(services);
    //ConfigureAssetStorageApiClientsWithTokenService(services);

    services.AddControllers();
}
```

Then add the configuration code like this:

```csharp title="Sample configuration code"
private static void ConfigureAssetStorageApiClientsBase(IServiceCollection services)
{
    // Registering custom configuration for API clients
    // Setup clients configuration in DI callback

    services.AddScoped<Aurigma.AssetStorage.IApiClientConfiguration>(s =>
    {
        return new Aurigma.AssetStorage.ApiClientConfiguration()
        {
            ApiUrl = "https://assetstorageapi.example.com/",
            // ... additional parameters will go here (see further)
        };
    });

    // Here, we register all API clients we are going to use. A separate API client exists 
    // for every section you can find in the API reference and the name is formed as 
    // _SectionName_ApiClient (and I_SectionName_ApiClient for the interface name). 
    //
    // For example, for the Designs, it will be DesignsApiClient and IDesignApiClient,
    // while for the PrivateDesigns, it will be PrivateDesignsApiClient and 
    // IPrivateDesignsApiClient.
    services.AddHttpClient<IDesignsApiClient, DesignsApiClient>();
    services.AddHttpClient<IPrivateDesignsApiClient, PrivateDesignsApiClient>();
}
```

**.NET Framework**

If you did not do it earlier, install the Autofac module from Nuget: 

```
Install-Package Autofac -Version 6.0.0
```

Then add these `using` to the **global.asax.cs**: 

```csharp title="Include Autofac"
using Autofac;
using Autofac.Integration.WebApi;
```

Then add this to the `Application_Start` method:

```csharp title="Setup Autofac" {5-16}
protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    var builder = new ContainerBuilder();

    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // Here we will set up API clients
    ConfigureAssetStorageApiClients(builder);

    var container = builder.Build();

    GlobalConfiguration.Configuration.DependencyResolver = 
        new AutofacWebApiDependencyResolver(container);
}
```

Now let's implement the `ConfigureAssetStorageApiClients` where we will configure the API client.

```csharp title="Configure API client"
private void ConfigureAssetStorageApiClients(ContainerBuilder builder)
{
    // Use single http client for all clients
    builder.RegisterType<HttpClient>()
        .AsSelf()
        .SingleInstance();

    // Registering custom configuration for every API client
    builder.RegisterType<Aurigma.AssetStorage.ApiClientConfiguration>()
        .As<Aurigma.AssetStorage.IApiClientConfiguration>()
        .InstancePerRequest()
        // Setup clients configuration in DI callback
        .OnActivating(e => 
        {
            // AssetStorage service API url
            e.Instance.ApiUrl = "https://assetstorageapi.example.com/";
            // Auth parameters go here (see further)
        });

    // Here, we register all API clients we are going to use. A separate API client exists 
    // for every section you can find in the API reference and the name is formed as 
    // _SectionName_ApiClient (and I_SectionName_ApiClient for the interface name). 
    //
    // For example, for the Designs, it will be DesignsApiClient and IDesignApiClient,
    // while for the PrivateDesigns, it will be PrivateDesignsApiClient and 
    // IPrivateDesignsApiClient.
    builder.RegisterType<DesignsApiClient>()
        .As<IDesignsApiClient>();
    builder.RegisterType<PrivateDesignsApiClient>()
        .As<IPrivateDesignsApiClient>();
}
```

Now, let's see how you can create and use instances of API clients in your controllers and services.

## 4. Use the API Client

Once you set up your clients using dependency injection, just add the appropriate client interfaces to the constructor. There is a separate client for each section in the [API clients](https://customerscanvas.com/docs/hub/dev-center/api/clients.md#net-client) topic. The interface name is **I**_SectionName_**ApiClient**. For example, if you need a client for [`Designs`](https://customerscanvas.com/docs/hub/dev-center/api/asset-storage.md#tag/designs), the interface name will be `IDesignsApiClient`. It will have the same methods as you can see in the reference with the `Async` prefix at the end.

Here is an example of a controller that uses API clients:

**.NET Core**

```csharp title="API client usage simple example"
[Authorize("Custom")]
[ApiController]
[Route("/")]
public class SampleController : ControllerBase
{
    private readonly IDesignsApiClient _client;

    public SampleController(IDesignsApiClient client)
    {
        _client = client;
    }

    [HttpGet("action")]
    public async Task<ActionResult> Action()
    {
        var result = await _client.GetAllAsync();

        return Ok(result);
    }
}
```

**.NET Framework**

```csharp title="API client usage simple example"
[CustomAuthorize]
public class SampleController : ApiController
{
    private readonly IDesignsApiClient _client;

    public SampleController(IDesignsApiClient client)
    {
        _client = client;
    }

    [HttpGet]
    [Route("action")]
    public async Task<IHttpActionResult> Action()
    {
        var result = await _client.GetAllAsync();

        return Ok(result);
    }
}
```

You can pass more than one interface. It is also possible to override API client settings you set up through dependency injection. 

**.NET Core**

```csharp title="API client usage example - override settings"
[Authorize("Custom")]
[ApiController]
[Route("/")]
public class Sample2Controller : ControllerBase
{
    private readonly IDesignsApiClient _client;
    private readonly IPrivateDesignsApiClient _privateClient;

    public Sample2Controller(IDesignsApiClient client, IPrivateDesignsApiClient privateClient, IHttpContextAccessor httpContextAccessor)
    {
        _client = client;
        _privateClient = privateClient;

        // we can override client settings 

        var token = httpContextAccessor?.HttpContext?.Request             
            .Headers["Authorization"].ToString().Replace("Bearer ", "");
        _client.AuthorizationToken = token;
        _privateClient.AuthorizationToken = token;
    }

    [HttpGet("action")]
    public async Task<ActionResult> Action()
    {
        var result = await _client.GetAllAsync();

        return Ok(result);
    }
}
```

**.NET Framework**

```csharp title="API client usage example - override settings"
public class Sample2Controller : ApiController
{
    private readonly IDesignsApiClient _client;
    private readonly IPrivateDesignsApiClient _privateClient;

    public Sample2Controller(IDesignsApiClient client, IPrivateDesignsApiClient privateClient)
    {
        _client = client;
        _privateClient = privateClient;

        // we can override client settings 
        var token = HttpContext.Current?.Request?.Headers["Authorization"]?
            .ToString().Replace("Bearer ", "");
        _client.AuthorizationToken = token;
        _privateClient.AuthorizationToken = token;
    }

    [HttpGet]
    [Route("action")]
    public async Task<IHttpActionResult> Action()
    {
        var result = await _client.GetAllAsync();

        return Ok(result);
    }
}
```

## 5. Authentication

To make successful API calls, it is necessary to authorize them. The API client supports multiple authentication methods. For details, see the [Authentication Guide](https://customerscanvas.com/docs/hub/dev-center/api/auth.md).

The main thing you configure when setting up a client is authentication:

1. Passing API Keys in the request header.
2. Sending authorization tokens received from a client in the request header.
3. Performing authorization on every request.
4. Using a service to cache the authorization result and to monitor the token expiration time.

Let's consider each of these methods.

### API Key

If you have an on-premises installation, and you don't need to use any sophisticated authentication methods, you may use the API Key. 

:::tip
When a configuration is static (like a fixed API key), you may create an API Client once, as a singleton.
:::

You may do so as follows: 

**.NET Core**

**Startup.cs** (`ConfigureServices` method):

```csharp title="Setting up API Key" {1,7}
private static void ConfigureAssetStorageApiClientsApiKey(IServiceCollection services)
{
    // Registering custom configuration for API clients
    // Setup clients configuration in DI callback

    services.AddSingleton<Aurigma.AssetStorage.IApiClientConfiguration>(s =>
    {
        return new Aurigma.AssetStorage.ApiClientConfiguration()
        {
            ApiUrl = "https://assetstorageapi.example.com/",
            // API key specified in the service AppSettings.config
            ApiKey = "YOUR_API_KEY",
        };
    });

    // Using HttpClientFactory for managing HttpClient lifetime
    services.AddHttpClient<IDesignAtomsServiceApiClient, DesignAtomsServiceApiClient>();
}
```

**.NET Framework**

**Global.asax.cs**:

```csharp title="Setting up API Key" {4,10}
void ConfigureAssetStorageApiClientsApiKey(ContainerBuilder builder)
{
    // Use single http client for all clients
    builder.RegisterType<HttpClient>()
        .AsSelf()
        .SingleInstance();

    // Registering custom configuration for API clients
    builder.RegisterType<Aurigma.AssetProcessor.ApiClientConfiguration>()
            .As<Aurigma.AssetStorage.IApiClientConfiguration>()
            .SingleInstance()
            // Setup clients configuration in DI callback
            .OnActivating(e =>
            {
                e.Instance.ApiUrl = "https://assetstorageapi.example.com/";
                // API key specified in the service AppSettings.config
                e.Instance.ApiKey = "ApiKey";
            });

    // Registering API clients
    builder.RegisterType<DesignsApiClient>()
            .As<IDesignsApiClient>();
}
```

:::note
API Key is not available when you are using Customer's Canvas installed on our servers. 
:::

### Token passthrough

This option will work for you if you already obtained an access token from our identity server (BackOffice). For example, if your application relies on the same identities that BackOffice does. 

Let's imagine that we pass the token from the client to the server using the **Authorization** header. In this case, you may pass this token to Asset Storage (or other Back-end service) as follows. 

:::warning
Avoid using a singleton in this scenario - otherwise you will receive the token only on the first request after the application starts.
:::

**.NET Core**

**Startup.cs** (`ConfigureServices` method):

```csharp title="Token passthrough" {9-10,16}
private static void ConfigureAssetStorageApiClientsToken(IServiceCollection services)
{
    // It is required to get access to an HTTP header inside a configuration code
    services.AddHttpContextAccessor();

    services.AddScoped<Aurigma.AssetProcessor.IApiClientConfiguration>(s =>
    {
        var httpContextAccessor = s.GetRequiredService<IHttpContextAccessor>();

        // Acquiring input token from request context
        var token = httpContextAccessor?.HttpContext?.Request
            .Headers["Authorization"].ToString().Replace("Bearer ", "");

        return new Aurigma.AssetProcessor.ApiClientConfiguration()
        {
            // Service API url
            ApiUrl = "https://assetstorageapi.example.com/",    
            AuthorizationToken = token
        };
    });

    // Using HttpClientFactory for managing HttpClient lifetime
    services.AddHttpClient<IDesignProcessorApiClient, DesignProcessorApiClient>();
    services.AddHttpClient<IPrivateDesignProcessorApiClient, PrivateDesignProcessorApiClient>();
}
```

**.NET Framework**

**Global.asax.cs**:

```csharp title="Token passthrough" {9-10,14}
void ConfigureAssetStorageApiClientsToken(ContainerBuilder builder)
{
    // Use single http client for all clients
    builder.RegisterType<HttpClient>()
        .AsSelf()
        .SingleInstance();

    // Registering custom configuration for API clients
    builder.RegisterType<Aurigma.AssetProcessor.ApiClientConfiguration>()
        .As<Aurigma.AssetStorage.IApiClientConfiguration>()
        .InstancePerRequest()
        // Setup clients configuration in DI callback
        .OnActivating(e =>
        {
            // Acquiring input token from request context
            var token = HttpContext.Current?.Request?.Headers["Authorization"]?
                .ToString().Replace("Bearer ", "");

            e.Instance.ApiUrl = "https://assetstorageapi.example.com/";
            // Setup Token in DI
            e.Instance.AuthorizationToken = token;
        });

    // Registering API clients
    builder.RegisterType<DesignProcessorApiClient>()
        .As<IDesignProcessorApiClient>();
    builder.RegisterType<PrivateDesignProcessorApiClient>()
        .As<IPrivateDesignProcessorApiClient>();
}
```

### Get a token before each request

It is not always possible to get a token beforehand. In this case, you can have your application request a token from the BackOffice service before each request.

To do so, we will create a custom implementation of the API Client configuration class. It will acquire a token through the OAuth2 protocol and we will use [IdentityModel package](https://identitymodel.readthedocs.io/en/latest/) to achieve this. You can install it from Nuget like this: 

```
Install-Package IdentityModel -Version 4.4.0
```

Now, create a new .cs file, for example, **SampleAssetStorageApiClientConfiguration.cs** and add the `using` directive to be able to use the IdentityModel:

```csharp title="Using IdentityModel"
using IdentityModel.Client;
```

then add this class there:

**.NET Core**

```csharp title="SampleAssetStorageApiClientConfiguration class"
public class SampleAssetStorageApiClientConfiguration : 
    Aurigma.AssetStorage.IApiClientConfiguration
{
    private readonly HttpClient _client;
    public SampleAssetStorageApiClientConfiguration(IHttpClientFactory clientFactory)
    {
        _client = clientFactory.CreateClient();
    }

    public async Task<string> GetAuthorizationTokenAsync()
    {
        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(
            new ClientCredentialsTokenRequest
            {
                // A token endpoint in the IdentityProvider (BackOffice token URL)
                Address = "http://backoffice.example.com/connect/token",

                // Client Id and Secret pair - you can register them in your 
                // BackOffice tenant control panel. 
                // NOTE: Be sure to provide all necessary scopes for this client!
                ClientId = "YOUR_CLIENT_ID",
                ClientSecret = "YOUR_CLIENT_SECRET"
            });

        if (tokenResponse.IsError)
        { 
            throw new Exception("Could not retrieve token.");
        }

        return tokenResponse.AccessToken;
    }

    public string GetApiKey()
    {
        return "";
    }

    public string GetApiUrl()
    {
        return "https://assetstorageapi.example.com/";
    }

}
```

Use it in the **Startup.cs** as follows:

```csharp title="Automatically get token"
private static void ConfigureAssetStorageApiClients(IServiceCollection services)
{
    // Registering custom configuration for API clients
    // Setup clients configuration in DI callback

    services
        .AddScoped<Aurigma.AssetStorage.IApiClientConfiguration, SampleAssetStorageApiClientConfiguration>();
    // Using HttpClientFactory for managing HttpClient lifetime
    services.AddHttpClient<IDesignsApiClient, DesignsApiClient>();
    services.AddHttpClient<IPrivateDesignsApiClient, PrivateDesignsApiClient>();
}
```

**.NET Framework**

```csharp title="SampleAssetStorageApiClientConfiguration class"
public class SampleAssetStorageApiClientConfiguration : 
    Aurigma.AssetStorage.IApiClientConfiguration
{
    private readonly HttpClient _client;
    public SampleAssetStorageApiClientConfiguration(HttpClient client)
    {
        _client = client;
    }

    public async Task<string> GetAuthorizationTokenAsync()
    {
        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(
            new ClientCredentialsTokenRequest
            {
                Address = "http://backoffice.example.com/connect/token",
                ClientId = "YOUR_CLIENT_ID",
                ClientSecret = "YOUR_CLIENT_SECRET"
            });

        if (tokenResponse.IsError)
        {
            throw new HttpException((int)HttpStatusCode.InternalServerError, 
                "Could not retrieve token.");
        }

        return tokenResponse.AccessToken;
    }

    public string GetApiKey()
    {
        return "";
    }

    public string GetApiUrl()
    {
        return "https://assetstorageapi.example.com/";
    }
}
```

Use it in the **Global.asax.cs** as follows:

```csharp title="Automatically get token" {8}
private void ConfigureAssetStorageApiClientsSampleConfig(ContainerBuilder builder)
{
    // Use single http client for all clients
    builder.RegisterType<HttpClient>()
        .AsSelf()
        .SingleInstance();

    // Note, the setup callback is no longer needed
    builder.RegisterType<SampleAssetStorageApiClientConfiguration>()
        .As<Aurigma.AssetStorage.IApiClientConfiguration>()
        .InstancePerRequest();

    builder.RegisterType<DesignsApiClient>()
        .As<IDesignsApiClient>();
    builder.RegisterType<PrivateDesignsApiClient>()
        .As<IPrivateDesignsApiClient>();
}
```

### Efficient way to get tokens

The method explained in the previous section works great if the amount of requests to Back-end services is low. However, acquiring a token per each request is not very efficient. You may want to cache a token and send a new authorization request only when it expires. 

To do so, we need to implement a class that is responsible for receiving the token from BackOffice (a _token service_). Create a new .cs file, for example, **TokenService.cs**: 

**.NET Core**

```csharp title="TokenService class implementation"
using IdentityModel.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace SampleDotNetCore
{
    class TokenInfo
    {
        public string AccessToken { get; set; }
        public DateTime ExpiryTime { get; set; }
    }

    public class TokenService
    {
        private readonly object _lockObject = new object();
        private readonly HttpClient _client;
        private TokenInfo _tokenInfo;

        public TokenService(IHttpClientFactory clientFactory)
        {
            _client = clientFactory.CreateClient();
        }

        public async Task<string> GetTokenAsync()
        {
            lock (_lockObject)
            {
                if (_tokenInfo != null && _tokenInfo.ExpiryTime >= DateTime.UtcNow)
                {
                    return _tokenInfo.AccessToken;
                }
                _tokenInfo = null;
            }

            var tokenResponse = await _client.RequestClientCredentialsTokenAsync(
                new ClientCredentialsTokenRequest
                {
                    Address = "http://backoffice.example.com/connect/token",
                    ClientId = "YOUR_CLIENT_ID",
                    ClientSecret = "YOUR_CLIENT_SECRET"
                });

            if (tokenResponse.IsError)
            {
                throw new Exception("Could not retrieve token.");
            }

            lock (_lockObject)
            {
                if (_tokenInfo == null)
                {
                    _tokenInfo = new TokenInfo()
                    {
                        AccessToken = tokenResponse.AccessToken,
                        ExpiryTime = DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn),
                    };
                }
            }

            return tokenResponse.AccessToken;
        }
    }
}
```

**.NET Framework**

```csharp title="TokenService class implementation"
using IdentityModel.Client;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

namespace SampleDotNetWebApi2
{
    class TokenInfo
    {
        public string AccessToken { get; set; }
        public DateTime ExpiryTime { get; set; }
    }

    public class TokenService
    {
        private readonly object _lockObject = new object();
        private readonly HttpClient _client;
        private TokenInfo _tokenInfo;

        public TokenService(HttpClient client)
        {
            _client = client;
        }

        public async Task<string> GetTokenAsync()
        {
            lock (_lockObject)
            {
                if (_tokenInfo != null && _tokenInfo.ExpiryTime >= DateTime.UtcNow)
                {
                    return _tokenInfo.AccessToken;
                }
                _tokenInfo = null;
            }

            var tokenResponse = await _client.RequestClientCredentialsTokenAsync(
                new ClientCredentialsTokenRequest
                {
                    Address = "http://backoffice.example.com/connect/token",
                    ClientId = "YOUR_CLIENT_ID",
                    ClientSecret = "YOUR_CLIENT_SECRET",
                });

            if (tokenResponse.IsError)
            {
                throw new HttpException((int)HttpStatusCode.InternalServerError, 
                    "Could not retrieve token.");
            }

            lock (_lockObject)
            {
                if (_tokenInfo == null)
                {
                    _tokenInfo = new TokenInfo()
                    {
                        AccessToken = tokenResponse.AccessToken,
                        ExpiryTime = DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn),
                    };
                }
            }

            return tokenResponse.AccessToken;
        }
    }
}
```

Now, let's create a custom implementation of an API Client configuration class. This implementation will use the token service to request a token every time you initialize the client.

Create a new .cs file, for example, **CustomAssetStorageApiClientConfiguration.cs**: 

**.NET Core**

```csharp title="CustomAssetStorageApiClientConfiguration class"
public class CustomAssetStorageApiClientConfiguration : 
    Aurigma.AssetStorage.ApiClientConfiguration
{
    public Func<Task<string>> TokenProvider;

    public override Task<string> GetAuthorizationTokenAsync()
    {
        return TokenProvider();
    }
}
```

Use it in the **Startup.cs**:

```csharp title="Automatically get token" {7,9,14}
private static void ConfigureAssetStorageApiClientsWithTokenService(IServiceCollection services)
{
    services.AddHttpClient();

    // Add a token service that is used to get tokens from BackOffice 
    services.AddSingleton<TokenService>();

    services.AddScoped<Aurigma.AssetStorage.IApiClientConfiguration>(s =>
    {
        // Receive an instance of the TokenService we have just registered above.
        var tokenService = s.GetRequiredService<TokenService>();

        return new CustomAssetStorageApiClientConfiguration()
        {
            ApiUrl = "https://assetstorageapi.example.com/",    
            // TokenProvider is a function that is called every time you need a token.
            // Let's just use our TokenService to receive the token.
            TokenProvider = () => tokenService.GetTokenAsync()
        };
    });
    // Using HttpClientFactory for managing HttpClient lifetime
    services.AddHttpClient<IDesignsApiClient, DesignsApiClient>();
    services.AddHttpClient<IPrivateDesignsApiClient, PrivateDesignsApiClient>();
}
```

**.NET Framework**

```csharp title="CustomAssetStorageApiClientConfiguration class"
public class CustomAssetStorageApiClientConfiguration : 
    Aurigma.AssetStorage.ApiClientConfiguration
{
    public Func<Task<string>> TokenProvider;
    
    public override Task<string> GetAuthorizationTokenAsync()
    {
        return TokenProvider();
    }
}
```

Use it in the **Global.asax.cs**:

```csharp title="Automatically get token" {8-10,12,19,28}
private void ConfigureAssetStorageApiClientsWithTokenService(ContainerBuilder builder)
{
    builder.RegisterType<HttpClient>()
        .AsSelf()
        .SingleInstance();

    // Add a token service that is used to get tokens from BackOffice 
    builder.RegisterType<TokenService>()                                             
        .AsSelf()
        .SingleInstance();

    builder.RegisterType<CustomAssetStorageApiClientConfiguration>()
        .As<Aurigma.AssetStorage.IApiClientConfiguration>()
        .InstancePerRequest()
        // Setup clients configuration in DI callback
        .OnActivating(e =>
        {
            // Receive an instance of the TokenService we have just registered above.
            var tokenService = e.Context.Resolve<TokenService>();

            // Acquiring input token from request context
            var token = HttpContext.Current?.Request?.Headers["Authorization"]?
                .ToString().Replace("Bearer ", "");

            e.Instance.ApiUrl = "https://assetstorageapi.example.com/";
            // TokenProvider is a function that is called every time you need a token.
            // Let's just use our TokenService to receive the token.
            e.Instance.TokenProvider = () => tokenService.GetTokenAsync();
            // Setup Token in DI
            e.Instance.AuthorizationToken = token;
        });

    builder.RegisterType<DesignsApiClient>()
        .As<IDesignsApiClient>();
}
```

## 6. Next Steps

- Explore the [Full API Reference](https://customerscanvas.com/docs/hub/dev-center/api.md).
- Learn about [Authentication](https://customerscanvas.com/docs/hub/dev-center/api/auth.md).
- Try other API clients: [Python](https://customerscanvas.com/docs/hub/dev-center/api/clients/python-api-client.md).

### Need Help?

[Submit a support ticket](https://customerscanvas.com/account/cases)
