Another solution: One of the tests in Refit uses this method. Add System.Reactive.Linq in nuget.
Then in the interface specification:
interface IDevice
{
    [Get("/app/device/{id}")]
    IObservable<Device> GetDevice(string id, [Header("Authorization")] string authorization);
}
And in the API:
try
{
  await device.GetDevice("your_parameters_here").Timeout(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
  Console.WriteLine("Timeout: " + e.Message);
}
+1 solution from here:
Create an extension method for your tasks:
public static class TaskExtensions
{
    public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
    {
        using (var timeoutCancellationTokenSource = new CancellationTokenSource())
        {
            var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));
            if (completedTask == task)
            {
                timeoutCancellationTokenSource.Cancel();
                return await task;  // Very important in order to propagate exceptions
            }
            else
            {
                throw new TimeoutException("The operation has timed out.");
            }
        }
    }
}
Interface can be left using Task<Device> return value. In the API:
try
{
  await _server.ListGasLines().TimeoutAfter(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
  Console.WriteLine("Timeout: " + e.Message);
}