Understanding Async Operations
All image and video generation operations in the Legnext API are asynchronous. When you submit a request, you receive ajob_id that you use to check the status and retrieve results.
Setup
Copy
using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Legnext.SDK.Api;
using Legnext.SDK.Client;
using Legnext.SDK.Extensions;
string apiKey = Environment.GetEnvironmentVariable("LEGNEXT_API_KEY");
var services = new ServiceCollection();
services.AddApi(config =>
{
config.AddApiHttpClients(client =>
{
client.BaseAddress = new Uri("https://api.legnext.ai");
});
});
var provider = services.BuildServiceProvider();
var videoApi = provider.GetRequiredService<IVideoApi>();
Checking Task Status
Check the status of a job:Copy
string jobId = "your-job-id";
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option<string>(apiKey)
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
if (root.TryGetProperty("status", out var status))
{
string statusValue = status.GetString();
Console.WriteLine($"Status: {statusValue}");
// Common statuses: "pending", "processing", "completed", "failed"
switch (statusValue)
{
case "completed":
// Extract results
if (root.TryGetProperty("output", out var output))
{
if (output.TryGetProperty("image_urls", out var imageUrls))
{
foreach (var url in imageUrls.EnumerateArray())
{
Console.WriteLine($"Image: {url.GetString()}");
}
}
}
break;
case "failed":
if (root.TryGetProperty("error", out var error))
{
Console.WriteLine($"Error: {error.GetString()}");
}
break;
case "pending":
case "processing":
Console.WriteLine("Task still in progress...");
break;
}
}
}
Polling for Completion
Poll a task until it completes:Copy
public async Task<JsonDocument> WaitForTaskCompletionAsync(
string jobId,
int maxAttempts = 60,
int delaySeconds = 5)
{
for (int i = 0; i < maxAttempts; i++)
{
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option<string>(apiKey)
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
if (root.TryGetProperty("status", out var status))
{
string statusValue = status.GetString();
if (statusValue == "completed")
{
Console.WriteLine("Task completed!");
return jsonDoc;
}
else if (statusValue == "failed")
{
throw new Exception("Task failed");
}
}
}
Console.WriteLine($"Attempt {i + 1}/{maxAttempts}: Waiting...");
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
}
throw new TimeoutException("Task did not complete in time");
}
Complete Example
Generate an image and wait for completion:Copy
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Legnext.SDK.Api;
using Legnext.SDK.Client;
using Legnext.SDK.Extensions;
class Program
{
static async Task Main(string[] args)
{
string apiKey = Environment.GetEnvironmentVariable("LEGNEXT_API_KEY");
var services = new ServiceCollection();
services.AddApi(config =>
{
config.AddApiHttpClients(client =>
{
client.BaseAddress = new Uri("https://api.legnext.ai");
});
});
var provider = services.BuildServiceProvider();
var imageApi = provider.GetRequiredService<IImageApi>();
var videoApi = provider.GetRequiredService<IVideoApi>();
// Step 1: Generate image
var request = new Dictionary<string, object>
{
{ "text", "a beautiful landscape" }
};
var generateResponse = await imageApi.ApiV1DiffusionPostAsync(
new Option<string>(apiKey),
request
);
string jobId = null;
if (generateResponse.IsOk)
{
var jsonDoc = JsonDocument.Parse(generateResponse.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobIdProp))
{
jobId = jobIdProp.GetString();
Console.WriteLine($"Job created: {jobId}");
}
}
if (jobId == null)
{
Console.WriteLine("Failed to create job");
return;
}
// Step 2: Poll until complete
for (int i = 0; i < 60; i++)
{
await Task.Delay(TimeSpan.FromSeconds(5));
var statusResponse = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option<string>(apiKey)
);
if (statusResponse.IsOk)
{
var jsonDoc = JsonDocument.Parse(statusResponse.RawContent);
var root = jsonDoc.RootElement;
if (root.TryGetProperty("status", out var status))
{
string statusValue = status.GetString();
Console.WriteLine($"Status: {statusValue}");
if (statusValue == "completed")
{
// Get image URLs
if (root.TryGetProperty("output", out var output) &&
output.TryGetProperty("image_urls", out var imageUrls))
{
Console.WriteLine("Generated images:");
foreach (var url in imageUrls.EnumerateArray())
{
Console.WriteLine($" - {url.GetString()}");
}
}
break;
}
else if (statusValue == "failed")
{
Console.WriteLine("Task failed");
break;
}
}
}
}
}
}
Error Handling
Handle errors during task polling:Copy
try
{
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option<string>(apiKey)
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
// Process response...
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode}");
Console.WriteLine($"Response: {response.RawContent}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
Best Practices
- Polling Interval: Use 5-10 second intervals to avoid rate limiting
- Timeout: Set a reasonable maximum wait time (5-10 minutes)
- Error Handling: Always check for “failed” status
- Cancellation: Support
CancellationTokenfor long-running operations