Skip to main content

Understanding Async Operations

All image and video generation operations in the Legnext API are asynchronous. When you submit a request, you receive a job_id that you use to check the status and retrieve results.

Setup

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:
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:
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:
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:
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

  1. Polling Interval: Use 5-10 second intervals to avoid rate limiting
  2. Timeout: Set a reasonable maximum wait time (5-10 minutes)
  3. Error Handling: Always check for “failed” status
  4. Cancellation: Support CancellationToken for long-running operations

Next Steps